Table of contents

Packages required

Load all of these packages before running any of the chunks of code in the subsections below.

library(tidyverse)
library(readxl)
library(data.table)
library(plotly)
library(Cairo)
library(lmtest)
library(car)
library(wesanderson)
library(ggbreak)
library(scales)
library(ggh4x)
library(ggtext)
library(drc)

Figure 1: Cobalt corrosion data for wild type cells, ∆phz mutants, spent medium, and abiotic controls in sterile medium

  1. Use the code below to load in source data.
All_cobalt_data_combined <- fread("All_cobalt_ICPMS_data_cleaned_formatted_20250513.txt", sep = "\t", header = "auto")
  1. Use the code below to generate the scatterplot containing the categories of interest.
#Adjust the presentation aesthetics
theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"),
        axis.text.x = element_text(color = "grey20", 
        size = 32, angle = 0, hjust = .5, vjust = .5, face = "plain"),
        axis.text.y = element_text(color = "grey20", 
        size = 32, angle = 0, hjust = 1, vjust = 0, face = "plain"),  
        axis.title.x = element_text(color = "grey20", 
        size = 34, angle = 0, hjust = .5, vjust = 0, face = "bold"),
        axis.title.y = element_text(color = "grey20", 
        size = 34, angle = 90, face = "bold"),
        strip.text.x = element_text(size = 32, colour = "grey20", face = "bold"),
        strip.text.y = element_text(size = 32, colour = "grey20"),
        plot.title = element_text(size = 30, face = "bold", hjust = .5),
        legend.title=element_text(size=32, face = "bold"), 
        legend.text=element_text(size=32),
        panel.border = element_rect(colour = "black", fill=NA, size=1))

#Create custom display orders
All_cobalt_data_combined$Abiotic_vs_biotic_ordered <- factor(All_cobalt_data_combined$Abiotic_vs_biotic,
                                                             levels = c("Wild type",
                                                                        "∆phz",
                                                                        "Spent medium",
                                                                        "Sterile medium"))

All_cobalt_data_combined$Metabolite_treatment_ordered <- factor(All_cobalt_data_combined$Metabolite_treatment,
                                                                 levels = c("Nothing added",
                                                                            "PCA",
                                                                            "MeOH"))
#Graphing script with additional data manipulation
library(wesanderson)
Abiotic_vs_biotic_treatment_scatterplot <- All_cobalt_data_combined %>%
                                           filter(DMSO_treatment == "No DMSO") %>% #use this to only focus on experiments that did not receive DMSO
                                           filter(Sample_preservation == "Acidified, filtered") %>% #216 observations
                                           group_by(Abiotic_vs_biotic, Wire_treatment, DMSO_treatment, Metabolite_treatment, Time) %>%
                                           mutate(
                                                  Mean_cobalt_concentration_ug_L = mean(Cobalt_concentration_ug_L),
                                                  Median_cobalt_concentration_ug_L = median(Cobalt_concentration_ug_L),
                                                  Stdev_cobalt_concentration_ug_L = sd(Cobalt_concentration_ug_L),
                                                  Min_cobalt_concentration_ug_L = min(Cobalt_concentration_ug_L),
                                                  Max_cobalt_concentration_ug_L = max(Cobalt_concentration_ug_L),
                                                  Mean_cobalt_concentration_uM = mean(Cobalt_concentration_uM),
                                                  Median_cobalt_concentration_uM = median(Cobalt_concentration_uM),
                                                  Stdev_cobalt_concentration_uM = sd(Cobalt_concentration_uM),
                                                  Min_cobalt_concentration_uM = min(Cobalt_concentration_uM),
                                                  Max_cobalt_concentration_uM = max(Cobalt_concentration_uM)) %>%
                                           relocate(Mean_cobalt_concentration_ug_L:Max_cobalt_concentration_uM, .after = Cobalt_concentration_uM) %>%
                                           filter(!Bottle_number == "1") %>% #remove outlier sterile control

                                          #plotting script
            
                                           ggplot(aes(x=Time, 
                                                      y = Mean_cobalt_concentration_uM, 
                                                      colour = Abiotic_vs_biotic_ordered, 
                                                      shape = Metabolite_treatment_ordered)) +
                                                  geom_point(size = 6) +
                                                  geom_errorbar(aes(ymin = Mean_cobalt_concentration_uM - Stdev_cobalt_concentration_uM,
                                                                    ymax = Mean_cobalt_concentration_uM + Stdev_cobalt_concentration_uM)) +
                                                  geom_line(aes(group = Bottle_number, color = Abiotic_vs_biotic_ordered))+
                                                  scale_x_continuous(breaks = seq(0, 168, by = 24)) +
                                                  facet_grid(~ Wire_treatment) +
                                                  ylab("Cobalt\nconcentration (µM)") +
                                                  xlab("Time elapsed (hours)") + 
                                                  scale_color_manual(name = "Abiotic vs biotic", 
                                                                     values = wes_palette("Darjeeling1", n = 4),
                                                                     labels = c("Wild type", 
                                                                              expression(italic("∆phz")),
                                                                              "Spent medium",
                                                                              "Sterile medium"))+
                                                  scale_shape_discrete(name = "Metabolite treatment") +
                                                  theme +
                                                  theme(plot.margin = unit(c(1,1,1,1), "cm"),
                                                        axis.title.x = element_text(vjust = -2),
                                                        axis.title.y = element_text(vjust = 2))
          
#Add a layer to angle the text
Abiotic_vs_biotic_treatment_scatterplot_angled <- Abiotic_vs_biotic_treatment_scatterplot + theme(axis.text.x = element_text(angle = 45))

#Save in different image formats at 300 dpi
ggsave("Fig1_Cobalt_ICPMS_data_abiotic_biotic_and_metabolite_treatments_no_DMSO_scatterplot_angled.jpg", dpi = 300, height=8, width=22, device= jpeg)
ggsave("Fig1_Cobalt_ICPMS_data_abiotic_biotic_and_metabolite_treatments_no_DMSO_scatterplot_angled.tiff", dpi = 300, height=8, width=22, device= tiff)
ggsave("Fig1_Cobalt_ICPMS_data_abiotic_biotic_and_metabolite_treatments_no_DMSO_scatterplot_angled.pdf", dpi = 300, height=8, width=22, device= cairo_pdf)

Figure S1: ANOVA test on cobalt concentrations sampled at 168 hours in biotic vs abiotic treatments with and without mass balance correction

Figure S1A: ANOVA test without recoveries applied

  1. Load the cobalt data and trim it where the wire was supplied.
All_cobalt_data_combined <- fread("All_cobalt_ICPMS_data_cleaned_formatted_20250513.txt", sep = "\t", header = "auto")

Abiotic_vs_biotic_wire_only_ANOVA_data <- All_cobalt_data_combined %>%
                                          filter(DMSO_treatment == "No DMSO") %>% 
                                          filter(Sample_preservation == "Acidified, filtered") %>% 
                                          filter(Time == 168) %>%
                                          filter(Metabolite_treatment == "Nothing added") %>%
                                          filter(Wire_treatment == "Wire included") #24 observations
  1. Generate the ANOVA model with type III sum of squares to account for the unbalanced design and interpret visualizations for linear model assumptions
Abiotic_vs_biotic_model <- lm(Cobalt_concentration_uM ~ Abiotic_vs_biotic, data = Abiotic_vs_biotic_wire_only_ANOVA_data, 
                              contrasts = list(Abiotic_vs_biotic = contr.sum), type =3)
G2;H2;Warningh: In lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
 extra argument ‘type’ will be disregardedg
Abiotic_vs_biotic_model

Call:
lm(formula = Cobalt_concentration_uM ~ Abiotic_vs_biotic, data = Abiotic_vs_biotic_wire_only_ANOVA_data, 
    contrasts = list(Abiotic_vs_biotic = contr.sum), type = 3)

Coefficients:
       (Intercept)  Abiotic_vs_biotic1  Abiotic_vs_biotic2  Abiotic_vs_biotic3  
            1392.9              1296.3              -832.6             -1095.6  
par(mfrow = c(2,2))
plot(Abiotic_vs_biotic_model)


#Run Breusch Pagan test for homoscedasticity
bptest(Abiotic_vs_biotic_model)

    studentized Breusch-Pagan test

data:  Abiotic_vs_biotic_model
BP = 8.3264, df = 3, p-value = 0.03973
#Run Shapiro-Wilk normality test
shapiro.test(Abiotic_vs_biotic_model$residuals)

    Shapiro-Wilk normality test

data:  Abiotic_vs_biotic_model$residuals
W = 0.95531, p-value = 0.3516
#Run Durbin-Watson test for autocorrelation
dwtest(Abiotic_vs_biotic_model)

    Durbin-Watson test

data:  Abiotic_vs_biotic_model
DW = 1.9404, p-value = 0.3295
alternative hypothesis: true autocorrelation is greater than 0

Interpretation

  • Homoscedasticity looks like it may be a slight issue especially as cobalt concentrations get higher.
  • There are a few slightly problematic values on the Q-Q residuals plot that may need to be addressed with a log transform (value 6 in particular).
  • BP test returns a p-value of 0.03973, so we reject the null hypothesis of homoscedasticity (as expected).
  • SW test returns a p-value of 0.3516, so we cannot reject the null hypothesis that residuals are normally distributed.
  • DW test returns a p-value of 0.3295, so we cannot reject the null hypothesis that there is no autocorrelation between data points.
  1. Re-run the model with a log10 transform to address the issues associated with homoscedasticity.
Abiotic_vs_biotic_model_log10 <- lm(log10(Cobalt_concentration_uM) ~ Abiotic_vs_biotic, data = Abiotic_vs_biotic_wire_only_ANOVA_data, 
                                    contrasts = list(Abiotic_vs_biotic = contr.sum), type =3)
G2;H2;Warningh: In lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
 extra argument ‘type’ will be disregardedg
Abiotic_vs_biotic_model_log10

Call:
lm(formula = log10(Cobalt_concentration_uM) ~ Abiotic_vs_biotic, 
    data = Abiotic_vs_biotic_wire_only_ANOVA_data, contrasts = list(Abiotic_vs_biotic = contr.sum), 
    type = 3)

Coefficients:
       (Intercept)  Abiotic_vs_biotic1  Abiotic_vs_biotic2  Abiotic_vs_biotic3  
            2.9668              0.4585             -0.2265             -0.5551  
par(mfrow = c(2,2))
plot(Abiotic_vs_biotic_model_log10)


#Run Breusch Pagan test for homoscedasticity
bptest(Abiotic_vs_biotic_model_log10)

    studentized Breusch-Pagan test

data:  Abiotic_vs_biotic_model_log10
BP = 2.8111, df = 3, p-value = 0.4217
#Run Shapiro-Wilk normality test
shapiro.test(Abiotic_vs_biotic_model_log10$residuals)

    Shapiro-Wilk normality test

data:  Abiotic_vs_biotic_model_log10$residuals
W = 0.91582, p-value = 0.04725
#Run Durbin-Watson test for autocorrelation
dwtest(Abiotic_vs_biotic_model_log10)

    Durbin-Watson test

data:  Abiotic_vs_biotic_model_log10
DW = 1.5357, p-value = 0.0736
alternative hypothesis: true autocorrelation is greater than 0

Interpretation

  • Homoscedasticity looks like it wikll be less of an issue, although now value point 1, the outlier, is problematic.
  • BP test returns a p-value of 0.4217, so we cannot reject the null hypothesis of homoscedasticity.
  • SW test returns a p-value of 0.04725, so we reject the null hypothesis that residuals are normally distributed.
  • DW test returns a p-value of 0.0736, so we cannot reject the null hypothesis that there is no autocorrelation between data points.

The issue with the potential outlier is back. This was a contaminated sterile control, so there is a biological reason to remove it from consideration.

  1. Re-run the model removing the outlier and then log10-transforming the data to address issues of normal distribution of residuals.
Abiotic_vs_biotic_wire_only_ANOVA_data_outlier_removed <- All_cobalt_data_combined %>%
                                                          filter(DMSO_treatment == "No DMSO") %>% 
                                                          filter(Sample_preservation == "Acidified, filtered") %>% 
                                                          filter(Time == 168) %>%
                                                          filter(Metabolite_treatment == "Nothing added") %>%
                                                          filter(Wire_treatment == "Wire included") %>%
                                                          filter(!Sample_name == "2024-02-20_168hr_Wire+Media_1_A-F") #suspected outlier

##Generate model
Abiotic_vs_biotic_model_log10_outlier_removed <- lm(log10(Cobalt_concentration_uM) ~ Abiotic_vs_biotic, 
                                                    data = Abiotic_vs_biotic_wire_only_ANOVA_data_outlier_removed , 
                                                    contrasts = list(Abiotic_vs_biotic = contr.sum), type =3)
G2;H2;Warningh: In lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
 extra argument ‘type’ will be disregardedg
Abiotic_vs_biotic_model_log10_outlier_removed

Call:
lm(formula = log10(Cobalt_concentration_uM) ~ Abiotic_vs_biotic, 
    data = Abiotic_vs_biotic_wire_only_ANOVA_data_outlier_removed, 
    contrasts = list(Abiotic_vs_biotic = contr.sum), type = 3)

Coefficients:
       (Intercept)  Abiotic_vs_biotic1  Abiotic_vs_biotic2  Abiotic_vs_biotic3  
            2.9527              0.4727             -0.2124             -0.5975  
par(mfrow = c(2,2))
plot(Abiotic_vs_biotic_model_log10_outlier_removed)


#Run Breusch Pagan test for homoscedasticity
bptest(Abiotic_vs_biotic_model_log10_outlier_removed)

    studentized Breusch-Pagan test

data:  Abiotic_vs_biotic_model_log10_outlier_removed
BP = 2.7282, df = 3, p-value = 0.4355
#Run Shapiro-Wilk normality test
shapiro.test(Abiotic_vs_biotic_model_log10_outlier_removed$residuals)

    Shapiro-Wilk normality test

data:  Abiotic_vs_biotic_model_log10_outlier_removed$residuals
W = 0.97364, p-value = 0.7751
#Run Durbin-Watson test for autocorrelation
dwtest(Abiotic_vs_biotic_model_log10_outlier_removed)

    Durbin-Watson test

data:  Abiotic_vs_biotic_model_log10_outlier_removed
DW = 1.9467, p-value = 0.3395
alternative hypothesis: true autocorrelation is greater than 0

Interpretation

  • Homoscedasticity looks okay as does the normal distribution of residuals.
  • BP test returns a p-value of 0.4355, so we cannot reject the null hypothesis of homoscedasticity.
  • SW test returns a p-value of 0.7751, so we cannot reject the null hypothesis that residuals are normally distributed.
  • DW test returns a p-value of 0.3395, so we cannot reject the null hypothesis that there is no autocorrelation between data points.

All linear model assumptions are met

  1. Generate the output of anova model generated with the data where the outlier removed and a log10 transformation was applied. This is returning a type 2 sum of squares because we are no longer considering the interaction having controlled for wire treatment
Abiotic_vs_biotic_type_II_ANOVA_results <- Anova(Abiotic_vs_biotic_model_log10_outlier_removed, type = 3)
Abiotic_vs_biotic_type_II_ANOVA_results
Anova Table (Type III tests)

Response: log10(Cobalt_concentration_uM)
                   Sum Sq Df   F value    Pr(>F)    
(Intercept)       179.347  1 11055.428 < 2.2e-16 ***
Abiotic_vs_biotic   4.736  3    97.323  1.03e-11 ***
Residuals           0.308 19                        
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Interpretation

  • There are significant differences in cobalt concentration at 168 hours that are attributable to the different abiotic vs biotic treatments.
  1. Run a Tukey post-hoc test to identify where the significant differences occur between treatments
#First you need to convert the model to an aov object
Abiotic_vs_biotic_model_log10_outlier_removed_converted <- aov(Abiotic_vs_biotic_model_log10_outlier_removed)
Tukey_comparison_abiotic_vs_biotic_model_log10_outlier_removed <- TukeyHSD(Abiotic_vs_biotic_model_log10_outlier_removed_converted, conf.level = 0.95)
Tukey_comparison_abiotic_vs_biotic_model_log10_outlier_removed
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Abiotic_vs_biotic_model_log10_outlier_removed)

$Abiotic_vs_biotic
                                  diff        lwr         upr     p adj
Spent medium-∆phz           -0.6850227 -0.9382649 -0.43178053 0.0000020
Sterile medium-∆phz         -1.0701513 -1.2853658 -0.85493679 0.0000000
Wild type-∆phz              -0.1354851 -0.3666625  0.09569234 0.3771351
Sterile medium-Spent medium -0.3851286 -0.6003430 -0.16991407 0.0003969
Wild type-Spent medium       0.5495376  0.3183602  0.78071506 0.0000120
Wild type-Sterile medium     0.9346662  0.7459106  1.12342176 0.0000000
Tukey_comparison_abiotic_vs_biotic_data_frame <- as.data.frame(Tukey_comparison_abiotic_vs_biotic_model_log10_outlier_removed$Abiotic_vs_biotic)

write.table(Tukey_comparison_abiotic_vs_biotic_data_frame, 
            file = "Tukey_comparison_results_abiotic_vs_biotic_log10_outlier_removed_20250401.txt", sep = "\t", 
            row.names = FALSE, col.names = TRUE) 

Interpretation

  • There are significant differences between:
    • Spent medium vs ∆phz
    • Sterile medium vs ∆phz
    • Sterile medium vs spent medium
    • Wild type vs spent medium
    • Wild type vs sterile medium
  • The only non-significant difference is between wild type and ∆phz
  • Letters to add to plots:
    • Wild type: A
    • ∆phz: A
    • Spent medium: B
    • Sterile medium: C
  1. Generate boxplots that will be used to overlay the Tukey annotations manually in an image editor
theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"),
        axis.text.x = element_text(color = "grey20", size = 16, angle = 0, hjust = 0.5, vjust = 0, face = "plain"),
        axis.text.y = element_text(color = "grey20", size = 16, angle = 0, hjust = 0.5, vjust = 0, face = "plain"),  
        axis.title.x = element_text(color = "grey20", size = 18, angle = 0, hjust = 0.5, vjust = -1, face = "plain"),
        axis.title.y = element_text(color = "grey20", size = 18, angle = 90, face = "plain"),
        strip.text.x = element_text(size = 20, colour = "grey20"),
        strip.text.y = element_text(size = 20, colour = "grey20"),
        plot.title = element_text(size = 18, face = "bold", hjust = 0.5, vjust = 1),
        legend.title=element_text(size=18), 
        legend.text=element_text(size=18),
        legend.position = "right",
        panel.border = element_rect(colour = "black", fill=NA, size=1))

#Create custom order to display x-axis

All_cobalt_data_combined$Abiotic_vs_biotic_ordered <- factor(All_cobalt_data_combined$Abiotic_vs_biotic,
                                                             levels = c("Wild type",
                                                                        "∆phz",
                                                                        "Spent medium",
                                                                        "Sterile medium"))

Abiotic_vs_biotic_wire_only_boxplot_log10 <- All_cobalt_data_combined %>%
                                             filter(DMSO_treatment == "No DMSO") %>% 
                                             filter(Sample_preservation == "Acidified, filtered") %>% 
                                             filter(Time == 168) %>%
                                             filter(Metabolite_treatment == "Nothing added") %>%
                                             filter(Wire_treatment == "Wire included") %>%
                                             filter(!Sample_name == "2024-02-20_168hr_Wire+Media_1_A-F") %>% #suspected outlier
      
                                             #Graphing script
                                             ggplot(aes(x=Abiotic_vs_biotic_ordered, y=log10(Cobalt_concentration_uM))) + 
                                             geom_boxplot() +
                                             geom_jitter(fill = "grey", colour = "black", width = 0.1, pch =21, stroke =1)+
                                             ylim(0, 3.5)+
                                             labs(title = "" ,
                                                  y = "log10(Cobalt concentration (µM))", 
                                                  x = "Abiotic and biotic treatments") +
                                             theme + #this calls the aesthetic theme variable
                                             theme(plot.margin = unit(c(1,1,1,1), "cm"),
                                                   axis.title.x = element_text(vjust = -2),
                                                   axis.title.y = element_text(vjust = 2))

Abiotic_vs_biotic_wire_only_boxplot_log10 #anotate this manually in an image editor

#Save files in different formats
ggsave("FigS1A_Cobalt_ICPMS_data_biotic_treatments_no_DMSO_boxplot_log10_20250514.jpg", dpi = 300, height=6, width=9, device= jpeg)
ggsave("FigS1A_Cobalt_ICPMS_data_biotic_treatments_no_DMSO_boxplot_log10_20250514.tiff", dpi = 300, height=6, width=9, device= tiff)
ggsave("FigS1A_Cobalt_ICPMS_data_biotic_treatments_no_DMSO_boxplot_log10_20250514.pdf", dpi = 300, height=6, width=9, device=cairo_pdf)

Fig S1B: ANOVA test with mass balance recoveries applied

  1. Load in the data from the manually adjusted tab-delimited file that contains recoveries. Generate a new variable where the recovery has been applied.
All_cobalt_data_combined_recoveries <- fread("All_cobalt_ICPMS_data_cleaned_formatted_20250513.txt", sep = "\t", header = "auto") %>%
                                       mutate(Cobalt_concentration_uM_corrected = Cobalt_concentration_uM/Recovery) %>% #apply recoveries
                                       relocate(Cobalt_concentration_uM_corrected, .after = Cobalt_concentration_uM)
  1. Run the model applying the same outlier removal and log-transformations used on the data that was not corrected for recovery.
Abiotic_vs_biotic_wire_only_ANOVA_data_outlier_removed_recoveries <- All_cobalt_data_combined_recoveries %>%
                                                                     filter(DMSO_treatment == "No DMSO") %>% 
                                                                     filter(Sample_preservation == "Acidified, filtered") %>% 
                                                                     filter(Time == 168) %>%
                                                                     filter(Metabolite_treatment == "Nothing added") %>%
                                                                     filter(Wire_treatment == "Wire included") %>%
                                                                     filter(!Sample_name == "2024-02-20_168hr_Wire+Media_1_A-F")

##Generate model
Abiotic_vs_biotic_model_log10_outlier_removed_recoveries <- lm(log10(Cobalt_concentration_uM_corrected) ~ Abiotic_vs_biotic, 
                                                            data = Abiotic_vs_biotic_wire_only_ANOVA_data_outlier_removed_recoveries, 
                                                            contrasts = list(Abiotic_vs_biotic = contr.sum), type =3)
G2;H2;Warningh: In lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
 extra argument ‘type’ will be disregardedg
Abiotic_vs_biotic_model_log10_outlier_removed_recoveries

Call:
lm(formula = log10(Cobalt_concentration_uM_corrected) ~ Abiotic_vs_biotic, 
    data = Abiotic_vs_biotic_wire_only_ANOVA_data_outlier_removed_recoveries, 
    contrasts = list(Abiotic_vs_biotic = contr.sum), type = 3)

Coefficients:
       (Intercept)  Abiotic_vs_biotic1  Abiotic_vs_biotic2  Abiotic_vs_biotic3  
            2.9402              0.3866             -0.1822             -0.5807  
par(mfrow = c(2,2))
plot(Abiotic_vs_biotic_model_log10_outlier_removed_recoveries)


#Run Breusch Pagan test for homoscedasticity
bptest(Abiotic_vs_biotic_model_log10_outlier_removed_recoveries)

    studentized Breusch-Pagan test

data:  Abiotic_vs_biotic_model_log10_outlier_removed_recoveries
BP = 2.7282, df = 3, p-value = 0.4355
#Run Shapiro-Wilk normality test
shapiro.test(Abiotic_vs_biotic_model_log10_outlier_removed_recoveries$residuals)

    Shapiro-Wilk normality test

data:  Abiotic_vs_biotic_model_log10_outlier_removed_recoveries$residuals
W = 0.97364, p-value = 0.7751
#Run Durbin-Watson test for autocorrelation
dwtest(Abiotic_vs_biotic_model_log10_outlier_removed_recoveries)

    Durbin-Watson test

data:  Abiotic_vs_biotic_model_log10_outlier_removed_recoveries
DW = 1.9467, p-value = 0.3395
alternative hypothesis: true autocorrelation is greater than 0

Interpretation

  • Homoscedasticity looks okay as does the normal distribution of residuals.
  • BP test returns a p-value of 0.4355, so we cannot reject the null hypothesis of homoscedasticity.
  • SW test returns a p-value of 0.7751, so we cannot reject the null hypothesis that residuals are normally distributed.
  • DW test returns a p-value of 0.3395, so we cannot reject the null hypothesis that there is no autocorrelation between data points.

All linear model assumptions are met

  1. Generate the actual output of anova model generated with the data where the outlier removed and a log10 transformation was applied. This is returning a type 2 sum of squares because we are not longer considering the interaction having controlled for wire treatment
Abiotic_vs_biotic_type_II_ANOVA_results_recoveries <- Anova(Abiotic_vs_biotic_model_log10_outlier_removed_recoveries, type = 3)
Abiotic_vs_biotic_type_II_ANOVA_results_recoveries
Anova Table (Type III tests)

Response: log10(Cobalt_concentration_uM_corrected)
                   Sum Sq Df   F value    Pr(>F)    
(Intercept)       177.840  1 10962.516 < 2.2e-16 ***
Abiotic_vs_biotic   4.414  3    90.699 1.925e-11 ***
Residuals           0.308 19                        
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Interpretation

  • There are significant differences in cobalt concentration at 168 hours that are attributable to the different abiotic vs biotic treatments even after correcting for recoveries.
  • The p-values are different for the recovery corrected data, but both version of the data have p < 0.001.
  1. Run a Tukey post-hoc test to figure out where the significant differences are.
library(data.table)
#First you need to convert the model to an aov object
Abiotic_vs_biotic_model_log10_outlier_removed_converted_recoveries <- aov(Abiotic_vs_biotic_model_log10_outlier_removed_recoveries)
Tukey_comparison_abiotic_vs_biotic_model_log10_outlier_removed_recoveries <- TukeyHSD(Abiotic_vs_biotic_model_log10_outlier_removed_converted_recoveries, conf.level = 0.95)
Tukey_comparison_abiotic_vs_biotic_model_log10_outlier_removed_recoveries
  Tukey multiple comparisons of means
    95% family-wise confidence level

Fit: aov(formula = Abiotic_vs_biotic_model_log10_outlier_removed_recoveries)

$Abiotic_vs_biotic
                                   diff        lwr        upr     p adj
Spent medium-∆phz           -0.56877805 -0.8220202 -0.3155359 0.0000256
Sterile medium-∆phz         -0.96735967 -1.1825741 -0.7521452 0.0000000
Wild type-∆phz              -0.01037323 -0.2415507  0.2208042 0.9992557
Sterile medium-Spent medium -0.39858162 -0.6137961 -0.1833671 0.0002701
Wild type-Spent medium       0.55840482  0.3272274  0.7895823 0.0000097
Wild type-Sterile medium     0.95698644  0.7682309  1.1457420 0.0000000
Tukey_comparison_abiotic_vs_biotic_data_frame_recoveries <- as.data.frame(Tukey_comparison_abiotic_vs_biotic_model_log10_outlier_removed_recoveries$Abiotic_vs_biotic)

write.table(Tukey_comparison_abiotic_vs_biotic_data_frame_recoveries, 
            file = "Tukey_comparison_results_abiotic_vs_biotic_log10_outlier_removed_recoveries_20250513.txt", sep = "\t", 
            row.names = FALSE, col.names = TRUE) 

Interpretation

  • There are significant differences between:
    • Spent medium vs ∆phz
    • Sterile medium vs ∆phz
    • Sterile medium vs spent medium
    • Wild type vs spent medium
    • Wild type vs sterile medium
  • The only non-significant difference is between wild type and ∆phz
  • Expected letters
    • Wild type: A
    • ∆phz: A
    • Spent medium: B
    • Sterile medium: C
  1. Regenerate boxplots that will be used to overlay the Tukey annotations manually.
theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"),
        axis.text.x = element_text(color = "grey20", size = 16, angle = 0, hjust = 0.5, vjust = 0, face = "plain"),
        axis.text.y = element_text(color = "grey20", size = 16, angle = 0, hjust = 0.5, vjust = 0, face = "plain"),  
        axis.title.x = element_text(color = "grey20", size = 18, angle = 0, hjust = 0.5, vjust = -1, face = "plain"),
        axis.title.y = element_text(color = "grey20", size = 18, angle = 90, face = "plain"),
        strip.text.x = element_text(size = 20, colour = "grey20"),
        strip.text.y = element_text(size = 20, colour = "grey20"),
        plot.title = element_text(size = 18, face = "bold", hjust = 0.5, vjust = 1),
        legend.title=element_text(size=18), 
        legend.text=element_text(size=18),
        legend.position = "right",
        panel.border = element_rect(colour = "black", fill=NA, size=1))

#Create custom order to display x-axis

All_cobalt_data_combined_recoveries$Abiotic_vs_biotic_ordered <- factor(All_cobalt_data_combined_recoveries$Abiotic_vs_biotic,
                                                                 levels = c("Wild type",
                                                                            "∆phz",
                                                                            "Spent medium",
                                                                            "Sterile medium"))

Abiotic_vs_biotic_wire_only_boxplot_log10_recoveries <- All_cobalt_data_combined_recoveries %>%
                                                        filter(DMSO_treatment == "No DMSO") %>% 
                                                        filter(Sample_preservation == "Acidified, filtered") %>% 
                                                        filter(Time == 168) %>%
                                                        filter(Metabolite_treatment == "Nothing added") %>%
                                                        filter(Wire_treatment == "Wire included") %>%
                                                        filter(!Sample_name == "2024-02-20_168hr_Wire+Media_1_A-F") %>% #suspected outlier
                
                                                        #Graphing script
                                                        ggplot(aes(x=Abiotic_vs_biotic_ordered, y=log10(Cobalt_concentration_uM_corrected))) + 
                                                        geom_boxplot() +
                                                        geom_jitter(fill = "grey", colour = "black", width = 0.1, pch =21, stroke =1)+
                                                        ylim(0, 3.5)+
                                                        labs(title = "" ,
                                                             y = "log10(Cobalt concentration (µM)\ncorrected for recovery)", 
                                                             x = "Abiotic and biotic treatments") +
                                                        theme + #this calls the aesthetic theme variable
                                                        theme(plot.margin = unit(c(1,1,1,1), "cm"),
                                                              axis.title.x = element_text(vjust = -2),
                                                              axis.title.y = element_text(vjust = 2))

Abiotic_vs_biotic_wire_only_boxplot_log10_recoveries #anotate this manually in an image editor
ggsave("FigS1B_Cobalt_ICPMS_data_biotic_treatments_no_DMSO_boxplot_log10_recoveries_applied_20250513.jpg", dpi = 300, height=6, width=9, device=jpeg)
ggsave("FigS1B_Cobalt_ICPMS_data_biotic_treatments_no_DMSO_boxplot_log10_recoveries_applied_20250513..tiff", dpi = 300, height=6, width=9, device=tiff)
ggsave("FigS1B_Cobalt_ICPMS_data_biotic_treatments_no_DMSO_boxplot_log10_recoveries_applied_20250513.pdf", dpi = 300, height=6, width=9, device=cairo_pdf)

Figure S2: ANOVA test on abiotic controls with and without phenazine-1-carboxylic acid

  1. Load the data frame from the compiled data and remove the outlier value from the sterile medium treatment that was contaminated.
All_cobalt_data_combined <- fread("All_cobalt_ICPMS_data_cleaned_formatted_20250513.txt", sep = "\t", header = "auto")

#Create custom order for x-axis
All_cobalt_data_combined$Abiotic_vs_biotic_ordered <- factor(All_cobalt_data_combined$Abiotic_vs_biotic,
                                                             levels = c("Wild type",
                                                                        "∆phz",
                                                                        "Spent medium",
                                                                        "Sterile medium"))

All_cobalt_data_combined$Metabolite_treatment_ordered <- factor(All_cobalt_data_combined$Metabolite_treatment,
                                                                 levels = c("Nothing added",
                                                                            "PCA",
                                                                            "MeOH"))
Abiotic_no_outlier <- All_cobalt_data_combined %>%
                      filter(DMSO_treatment == "No DMSO") %>% #use this to only focus on experiments that did not receive DMSO
                      filter(Sample_preservation == "Acidified, filtered") %>% #216 observations
                      filter(Time == 168 & Wire_treatment == "Wire included") %>% #Only look at no metabolite spikes + 168 hours
                      filter(Abiotic_vs_biotic_ordered == "Sterile medium") %>%
                      filter(!Sample_name == "2024-02-20_168hr_Wire+Media_1_A-F") #remove outlier
  1. Generate the linear models and verify assumptions for the ANOVA using type III sum of squares.
##Generate model
Abiotic_model_outlier_removed <- lm(Cobalt_concentration_uM ~ Metabolite_treatment, 
                                    data = Abiotic_no_outlier, 
                                    contrasts = list(Metabolite_treatment = contr.sum), type =3)
G2;H2;Warningh: In lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
 extra argument ‘type’ will be disregardedg
Abiotic_model_outlier_removed

Call:
lm(formula = Cobalt_concentration_uM ~ Metabolite_treatment, 
    data = Abiotic_no_outlier, contrasts = list(Metabolite_treatment = contr.sum), 
    type = 3)

Coefficients:
          (Intercept)  Metabolite_treatment1  Metabolite_treatment2  
              213.898                  8.048                 23.949  
par(mfrow = c(2,2))
plot(Abiotic_model_outlier_removed)


#Run Breusch Pagan test for homoscedasticity
bptest(Abiotic_model_outlier_removed)

    studentized Breusch-Pagan test

data:  Abiotic_model_outlier_removed
BP = 2.6841, df = 2, p-value = 0.2613
#Run Shapiro-Wilk normality test
shapiro.test(Abiotic_model_outlier_removed$residuals)

    Shapiro-Wilk normality test

data:  Abiotic_model_outlier_removed$residuals
W = 0.93943, p-value = 0.3753
#Run Durbin-Watson test for autocorrelation
dwtest(Abiotic_model_outlier_removed)

    Durbin-Watson test

data:  Abiotic_model_outlier_removed
DW = 2.8872, p-value = 0.9188
alternative hypothesis: true autocorrelation is greater than 0

Interpretation

  • Homoscedasticity may be an issue, it looks like samples associated with higher cobalt concentrations ~ 240 µM have higher variance.
  • Normal distribution of residuals looks good.
  • BP test returns a p-value of 0.2613 –> we cannot reject the null hypothesis of homoscedasticity.
  • SW test returns a p-value of 0.3753 –> we cannot reject the null hypothesis of normally distributed residuals.
  • DW test returns a p-value of 0.9188 –> we cannot reject the null hypothesis that there is no autocorrelation between data points.

All assumptions met, okay to proceed with ANOVA

  1. Run the ANOVA and the Tukey comparison.
Abiotic_type_III_ANOVA_results <- Anova(Abiotic_model_outlier_removed, type = 3)
Abiotic_type_III_ANOVA_results
Anova Table (Type III tests)

Response: Cobalt_concentration_uM
                     Sum Sq Df  F value    Pr(>F)    
(Intercept)          529421  1 128.8876 8.946e-08 ***
Metabolite_treatment   7051  2   0.8583    0.4483    
Residuals             49291 12                       
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Interpretation

  • Metabolite treatment did not emerge as a significant variable, so there is no significant differences between groups.
  1. Generate the boxplot. There is no need to annotate the boxes later because there are no significant differences.
Abiotic_outlier_removed_boxplot <- Abiotic_no_outlier %>%
                                   ggplot(aes(x=Metabolite_treatment_ordered, y=Cobalt_concentration_uM)) + 
                                   geom_boxplot() +
                                   geom_jitter(fill = "grey", colour = "black", width = 0.1, pch =21, stroke =1)+
                                   ylim(0, 400) +
                                   labs(title = "" ,
                                   y = "Cobalt concentration (µM)", 
                                   x = "Metabolic treatments in sterile medium") +
                                   theme +
                                   theme(plot.margin = unit(c(1,1,1,1), "cm"),
                                         axis.title.x = element_text(vjust = -2),
                                         axis.title.y = element_text(vjust = 2))
Abiotic_outlier_removed_boxplot
ggsave("FigS2_Cobalt_ICPMS_data_abiotic_treatments_no_DMSO_boxplot.jpg", dpi = 300, height=6, width=6, device=jpeg)
ggsave("FigS2_Cobalt_ICPMS_data_abiotic_treatments_no_DMSO_boxplot.tiff", dpi = 300, height=6, width=6, device=tiff)
ggsave("FigS2_Cobalt_ICPMS_data_abiotic_treatments_no_DMSO_boxplot.pdf", dpi = 300, height=6, width=6, device=cairo_pdf)

Figure 2: Phenazine metabolite concentrations measured via LC-HRMS

  1. Load the formatted LC-HRMS data.
LC_MS_data_combined_labelled_long <- fread("LC_MS_data_combined_20250419.txt", sep = "\t", header = "auto")
  1. Plot the stacked bar graphs using variables with a custom order.
barplot_theme<-  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
                 panel.background = element_blank(), axis.line = element_line(colour = "black"),
                 axis.text.x = element_text(color = "black", size = 32),
                 axis.text.y = element_text(color = "black", size = 32),
                 axis.title.x = element_text(color = "black", size = 34, vjust = -3, face = "bold"),
                 axis.title.y = element_text(color = "black", size = 34, vjust = 6, face = "bold"),
                 strip.text.x = element_text(color = "black", size = 32, face = "bold"),
                 strip.text.y = element_text(color = "black", size = 32, face = "bold"),
                 legend.title=element_text(size=40, vjust = 2, face = "bold"), 
                 legend.text=element_text(size=34),
                 legend.key = element_rect(fill = "white", color = NA),
                 plot.title = element_text(size = 68, face = "bold", hjust = 0.5),
                 panel.border = element_rect(colour = "black", fill=NA, size=1),
                 plot.margin = unit(c(2, 2, 2, 2), "cm"))

LC_MS_data_combined_labelled_long$Abiotic_vs_biotic_ordered <- factor(LC_MS_data_combined_labelled_long$Abiotic_vs_biotic, 
                                                                      levels = c("Wild type",
                                                                            "Spent medium",
                                                                            "∆phz"))

LC_MS_data_combined_labelled_long$Metabolite_ordered <- factor(LC_MS_data_combined_labelled_long$Metabolite, 
                                                                      levels = c("2-OHPCA",
                                                                            "PCA",
                                                                            "2-OHPHZ"))


Phenazine_barplot <-   LC_MS_data_combined_labelled_long %>%
                       group_by(Comment) %>%
                       mutate(Mean_concentration_ug_mL = mean(Concentration_ug_mL)) %>%
                       ggplot(aes(x= Time, y = Concentration_ug_mL, fill = Metabolite_ordered)) +
                       geom_bar(aes(group = Replicate), position="stack", stat="identity") +
                       facet_nested(Replicate~Wire_treatment + Abiotic_vs_biotic_ordered)+
                       scale_x_continuous(breaks = seq(0, 168, by = 24)) +
                       scale_fill_manual(name = "Metabolite", 
                                         values = c("2-OHPCA" = "#FA1F1E",   # Red
                                                    "PCA" = "#EBA602",       # Gold
                                                    "2-OHPHZ" = "#027AB0"    # Blue
                                                    ))+
                       #scale_fill_brewer(name = "Metabolite", palette = "YlOrRd")+ 
                       ylim(0,15) +
                       theme(axis.text.x=element_text(angle=0, hjust=0.5),
                       axis.title.y = element_text(color = "black", size = 24, vjust = 0))+
                       labs(x = "Time elapsed (hours)" , y = "Concentration (µg/mL)") +
                       barplot_theme + 
                       theme(legend.key.size = unit(2, 'cm'))

Phenazine_barplot

Phenazine_barplot_angled <- Phenazine_barplot + theme(axis.text.x = element_text(angle = 45, vjust = 0.5))

#Save in different image formats
ggsave("Fig2_phenazine_LCMS_data_stacked_barplot_faceted.jpg", dpi = 300, height=12, width=40, device=jpeg)
ggsave("Fig2_phenazine_LCMS_data_stacked_barplot_faceted.tiff", dpi = 300, height=12, width=40, device=tiff)
ggsave("Fig2_phenazine_LCMS_data_stacked_barplot_faceted.pdf", dpi = 300, height=12, width=40, device=cairo_pdf)

Figure 3: Wild type vs ∆phz mutant cell growth in corrosion assays

  1. Load the plate count data.
Plate_counts_combined <- fread("Plate_counts_combined_20250527.txt", sep = "\t", header = "auto")
  1. Add new variables to the data frame parsing the Comment variable that contains detailed informtion on the sample
Plate_counts_combined_treatments_added <- Plate_counts_combined %>%
                                          #Add time as a numeric vairable
                                          mutate(Time = case_when(grepl("0hr", Comment) ~ "0",
                                                                  grepl("24hr", Comment) ~ "24",
                                                                  grepl("72hr", Comment) ~ "72",
                                                                  grepl("168hr", Comment) ~ "168")) %>%
  
                                          mutate(Time = as.numeric(Time)) %>%
        
                                          #Add wire treatment as a dedicated variable and leave as character
                                          mutate(Wire_treatment = case_when(grepl("_Wire", Comment) ~ "Wire included",
                                                                            grepl("NoWire", Comment) ~ "No wire")) %>%
  
  
                                          #Add strain information
                                          mutate(Strain = case_when(grepl("+10%inoc_", Comment) ~ "Wild type",
                                                                    grepl("DMSO", Comment) ~ "Wild type",
                                                                    grepl("0%inoc∆phz", Comment) ~ "∆phz")) %>%
  
                                          #Add DMSO information
                                          mutate(DMSO_treatment = case_when(!grepl("DMSO", Comment) ~ "No DMSO",
                                                                            grepl("+DMSO", Comment) ~ "DMSO")) 

Plate_counts_combined_summary_statistics <- Plate_counts_combined_treatments_added %>%
                                            group_by(Strain, Wire_treatment, DMSO_treatment, Flask_number, Time) %>%
                                            filter(CFU_mL >0) %>% #remove any values that had 0 counts on the plate for graphing
            
                                            #Calculate plate counts using technical replicates for each flask at each time point
                                            mutate(Technical_mean_CFU_mL = mean(CFU_mL),
                                                   Technical_stdev_CFU_mL = sd(CFU_mL)) %>%
                              
                                             ungroup() %>%
                            
                                             #Calculate plate counts using average of technical replicates for all flasks (biological replicates)
                                             group_by(Strain, Wire_treatment, DMSO_treatment, Time) %>%
                                             
                                             mutate(Biological_mean_CFU_mL = mean(Technical_mean_CFU_mL),
                                                    Biological_stdev_CFU_mL = sd(Technical_mean_CFU_mL))

write.table(Plate_counts_combined_summary_statistics, file = "Plate_counts_combined_summary_statistics_20250419.txt", sep = "\t", 
            row.names = FALSE, col.names = TRUE) 
  1. Plot the growth data, summarizing the means and standard deviations prior to the ggplot command.
#Adjust the presentation aesthetics
theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"),
        axis.text.x = element_text(color = "grey20", 
        size = 32, angle = 0, hjust = .5, vjust = .5, face = "plain"),
        axis.text.y = element_text(color = "grey20", 
        size = 32, angle = 0, hjust = 1, vjust = 0, face = "plain"),  
        axis.title.x = element_text(color = "grey20", 
        size = 34, angle = 0, hjust = .5, vjust = 0, face = "bold"),
        axis.title.y = element_text(color = "grey20", 
        size = 34, angle = 90, face = "bold"),
        strip.text.x = element_text(size = 32, colour = "grey20", face = "bold"),
        strip.text.y = element_text(size = 32, colour = "grey20"),
        plot.title = element_text(size = 30, face = "bold", hjust = .5),
        legend.title=element_text(size=32, face = "bold"), 
        legend.text=element_text(size=32),
        panel.border = element_rect(colour = "black", fill=NA, size=1))

#Create custom display orders
Plate_counts_combined_treatments_added$Strain_ordered <- factor(Plate_counts_combined_treatments_added$Strain,
                                                             levels = c("Wild type",
                                                                        "∆phz",
                                                                        "Spent medium",
                                                                        "Sterile medium"))


Growth_curves_log_scale <- Plate_counts_combined_treatments_added %>%
                           filter(DMSO_treatment == "No DMSO") %>% #use this to only focus on experiments that did not receive DMSO
                           group_by(Strain, Wire_treatment, DMSO_treatment, Flask_number, Time) %>%
  
                           filter(CFU_mL >0) %>% #remove any values that had 0 counts on the plate for graphing
            
                           #Calculate plate counts using technical replicates for each flask at each time point
                           mutate(Technical_mean_CFU_mL = mean(CFU_mL),
                                  Technical_stdev_CFU_mL = sd(CFU_mL)) %>%
            
                           ungroup() %>%
          
                           #Calculate plate counts using average of technical replicates for all flasks (biological replicates)
                           group_by(Strain, Wire_treatment, DMSO_treatment, Time) %>%
                           
                           mutate(Biological_mean_CFU_mL = mean(Technical_mean_CFU_mL),
                                  Biological_stdev_CFU_mL = sd(Technical_mean_CFU_mL)) %>%
                           
                           #plotting script
                      
                           ggplot(aes(x=Time, y = log10(Biological_mean_CFU_mL), colour = Strain_ordered)) +
                           geom_point(size = 6) +
                           geom_errorbar(aes(ymin = log10(Biological_mean_CFU_mL - Biological_stdev_CFU_mL),
                                             ymax = log10(Biological_mean_CFU_mL + Biological_stdev_CFU_mL))) +
                           geom_line(aes(group = Flask_number, color = Strain_ordered))+
                           scale_x_continuous(breaks = seq(0, 168, by = 24))+
                           facet_grid(~ Wire_treatment) +
                           ylab("Log10\n(CFU/mL)") +
                           scale_y_continuous(labels = label_math(), limits = c(5, 10))+
                           xlab("Time elapsed (hours)") + 
                           scale_color_manual(name = "Strain", 
                                                     values = wes_palette("Darjeeling1", n = 4),
                                                     labels = c("Wild type", 
                                                              expression(italic("∆phz"))))+
                           theme +
                           theme(plot.margin = unit(c(1,1,1,1), "cm"),
                                 axis.title.x = element_text(vjust = -2),
                                 axis.title.y = element_text(vjust = 2))
          
Growth_curves_log_scale

Growth_curves_log_scale_no_legend_angled <- Growth_curves_log_scale + theme(axis.text.x = element_text(angle = 45))

ggsave("Fig3_plate_count_data_WT_phz_mutant_scatterplot_log10.jpg", dpi = 300, height=8, width=20, device=jpeg)
ggsave("Fig3_plate_count_data_WT_phz_mutant_scatterplot_log10.tiff", dpi = 300, height=8, width=20, device=tiff)
ggsave("Fig3_plate_count_data_WT_phz_mutant_scatterplot_log10.pdf", dpi = 300, height=8, width=20, device=cairo_pdf)

Figure S5: Cobalt concentrations for wild type cells that were acidified then filtered, or filtered then acidified

  1. Use the code below to load in source data.
All_cobalt_data_combined <- fread("All_cobalt_ICPMS_data_cleaned_formatted_20250513.txt", sep = "\t", header = "auto")
  1. Use this code to create a similar figure to Figure 1 comparing wild type and sterile medium treatments that did not receive DMSO and were subject to different sample preservation methods.
#Adjust the presentation aesthetics
theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"),
        axis.text.x = element_text(color = "grey20", 
        size = 32, angle = 0, hjust = .5, vjust = .5, face = "plain"),
        axis.text.y = element_text(color = "grey20", 
        size = 32, angle = 0, hjust = 1, vjust = 0, face = "plain"),  
        axis.title.x = element_text(color = "grey20", 
        size = 34, angle = 0, hjust = .5, vjust = 0, face = "bold"),
        axis.title.y = element_text(color = "grey20", 
        size = 34, angle = 90, face = "bold"),
        strip.text.x = element_text(size = 32, colour = "grey20", face = "bold"),
        strip.text.y = element_text(size = 32, colour = "grey20"),
        plot.title = element_text(size = 30, face = "bold", hjust = .5),
        legend.title=element_text(size=32, face = "bold"), 
        legend.text=element_text(size=32),
        panel.border = element_rect(colour = "black", fill=NA, size=1))


#Graphing script with additional data manipulation
Acidify_filter_scatterplot <-  All_cobalt_data_combined %>%
                               filter(Wire_treatment == "Wire included") %>% #use this to only focus on experiments that did not receive DMSO
                               filter(Abiotic_vs_biotic == "Wild type" | Abiotic_vs_biotic == "Sterile medium") %>%
                               filter(Metabolite_treatment == "Nothing added") %>%
                               filter(DMSO_treatment == "No DMSO") %>% #96 observations
                               group_by(Abiotic_vs_biotic, Wire_treatment, DMSO_treatment, Metabolite_treatment, Time, Sample_preservation) %>%
                               mutate(
                                      Mean_cobalt_concentration_ug_L = mean(Cobalt_concentration_ug_L),
                                      Median_cobalt_concentration_ug_L = median(Cobalt_concentration_ug_L),
                                      Stdev_cobalt_concentration_ug_L = sd(Cobalt_concentration_ug_L),
                                      Min_cobalt_concentration_ug_L = min(Cobalt_concentration_ug_L),
                                      Max_cobalt_concentration_ug_L = max(Cobalt_concentration_ug_L),
                                      Mean_cobalt_concentration_uM = mean(Cobalt_concentration_uM),
                                      Median_cobalt_concentration_uM = median(Cobalt_concentration_uM),
                                      Stdev_cobalt_concentration_uM = sd(Cobalt_concentration_uM),
                                      Min_cobalt_concentration_uM = min(Cobalt_concentration_uM),
                                      Max_cobalt_concentration_uM = max(Cobalt_concentration_uM)) %>%
                              relocate(Mean_cobalt_concentration_ug_L:Max_cobalt_concentration_uM, 
                                       .after = Cobalt_concentration_uM) %>%
                                filter(!Bottle_number == "1") %>% #remove outlier sterile control
  
                              #plotting script
  
                               ggplot(aes(x=Time, 
                                          y = Mean_cobalt_concentration_uM, 
                                          colour = Abiotic_vs_biotic,
                                          )) +
                                      geom_point(size = 6) +
                                      geom_errorbar(aes(ymin = Mean_cobalt_concentration_uM - Stdev_cobalt_concentration_uM,
                                                        ymax = Mean_cobalt_concentration_uM + Stdev_cobalt_concentration_uM)) +
                                      geom_line(aes(group = Bottle_number, color = Abiotic_vs_biotic))+
                                      scale_x_continuous(breaks = seq(0, 168, by = 24)) +
                                      facet_grid(~ Sample_preservation) +
                                      ylab("Cobalt concentration (µM)") +
                                      xlab("Time elapsed (hours)") + 
                                      scale_color_manual(name = "Abiotic vs biotic", 
                                                         values = wes_palette("Cavalcanti1", n = 2))+
                                      #scale_shape_discrete(name = "Abiotic vs biotic") +
                                      theme +
                                      theme(plot.margin = unit(c(1,1,1,1), "cm"),
                                            axis.title.x = element_text(vjust = -2),
                                            axis.title.y = element_text(vjust = 2),
                                            axis.text.x = element_text(angle = 45))

Acidify_filter_scatterplot

#Save the images in different formats
ggsave("FigS5_cobalt_ICPMS_data_sample_preservation_scatterplot.jpg", dpi = 300, height=8, width=20, device=jpeg)
ggsave("FigS5_cobalt_ICPMS_data_sample_preservation_scatterplot.tiff", dpi = 300, height=8, width=20, device=tiff)
ggsave("FigS5_cobalt_ICPMS_data_sample_preservation_scatterplot.pdf", dpi = 300, height=8, width=20, device=cairo_pdf)

Figure S6. Dose response curves for wild type cell growth rate as a function of cobalt concentration

  1. Load the summaries generated with the ‘growthcurver’ package that are the source data for the dose response curve.
P_chlor_aur_growth_summary_variables_added <- fread("Pseudomonas_chlororaphis_aurefociens_growth_curve_summaries.txt", sep = "\t", header = "auto")
  1. Use the commands in the ‘drc’ package to fit a 5 parameter logistic regression to create the dose response curve. Use the summary commands to get quick information on the IC/EC50 values for cobalt concentration.
P_chlor_aur_growth_rate_5_param_model<- drm(r ~ Cobalt_concentration_uM_numeric, 
                                            data = P_chlor_aur_growth_summary_variables_added, 
                                            fct = LL.5())
Warning :NaNs produced
Warning :NaNs produced
Warning :NaNs produced
Warning :NaNs produced
Warning :NaNs produced
Warning :NaNs produced
Warning :NaNs produced
Warning :NaNs produced
summary(P_chlor_aur_growth_rate_5_param_model)

Model fitted: Generalized log-logistic (ED50 as parameter) (5 parms)

Parameter estimates:

               Estimate Std. Error t-value   p-value    
b:(Intercept)  8.360166  19.277199  0.4337    0.6694    
c:(Intercept)  0.206760   0.012806 16.1451 1.499e-12 ***
d:(Intercept)  0.461770   0.020284 22.7657 3.048e-15 ***
e:(Intercept) 26.583930  69.763176  0.3811    0.7074    
f:(Intercept)  2.008672  34.513367  0.0582    0.9542    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error:

 0.04959386 (19 degrees of freedom)
P_chlor_aur_growth_rate_summary_dose_data <- ED(P_chlor_aur_growth_rate_5_param_model, c(5, 10, 50), interval = "delta")

Estimated effective doses

       Estimate Std. Error    Lower    Upper
e:1:5   17.1694    14.5636 -13.3126  47.6514
e:1:10  18.7436    12.7079  -7.8543  45.3415
e:1:50  23.9093     3.7162  16.1313  31.6874
  1. Plot the dose response curve using base R (most compatible with the drc package).
P_chlor_aur_growth_rate_dose_response<- plot(P_chlor_aur_growth_rate_5_param_model, broken = FALSE, type = "all",
                                        xlab = "Co(2+) concentration (µM)", xlim = c(0, 1000),
                                        ylab = "Growth rate (hr-1)", 
                                        main = "Pseudomonas chlororaphis aureofaciens growth curve in response to Co(2+)")
                                        
view(P_chlor_aur_growth_rate_dose_response)
ggsave("FigS6_Pseudomonas_chlororaphis_aureofaciens_growth_rate_cobalt_dose_response_curve.jpg", height=8, width=14, device=jpeg)

#Save in different formats
pdf(file = 'FigS6_Pseudomonas_chlororaphis_aureofaciens_growth_rate_cobalt_dose_response_curve.pdf')
plot(P_chlor_aur_growth_rate_5_param_model, broken = FALSE, type = "all",
xlab = "Co(2+) concentration (µM)", xlim = c(0, 1000),
ylab = "Growth rate (hr-1)", 
main = "Pseudomonas chlororaphis aureofaciens \ngrowth curve in response to Co(2+)")
dev.off()
quartz_off_screen 
                2 

#Figure S14: ANOVA test on live cells with and without DMSO

  1. Load the source data and trim it to the desired samples to carry out the comparison for the effect of DMSO.
All_cobalt_data_combined <- fread("All_cobalt_ICPMS_data_cleaned_formatted_20250513.txt", sep = "\t", header = "auto")

#Subet DMSO data
DMSO_comparison_data <- All_cobalt_data_combined %>%
                        filter(Wire_treatment == "Wire included") %>%
                        filter(Sample_preservation == "Acidified, filtered") %>%
                        filter(Time == 168) %>%
                        filter(Abiotic_vs_biotic == "Wild type")
  1. Use the subset data to generate a linear model that for an ANOVA comparison. Use this code to verify the assumptions of linear model fit.
DMSO_comparison_model <- lm(Cobalt_concentration_uM ~ DMSO_treatment, data = DMSO_comparison_data,
                            contrasts = list(DMSO_treatment = contr.sum), type =3) #need to do this for unabalance sample size
G2;H2;Warningh: In lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
 extra argument ‘type’ will be disregardedg
DMSO_comparison_model

Call:
lm(formula = Cobalt_concentration_uM ~ DMSO_treatment, data = DMSO_comparison_data, 
    contrasts = list(DMSO_treatment = contr.sum), type = 3)

Coefficients:
    (Intercept)  DMSO_treatment1  
         1205.1           -819.8  
par(mfrow = c(2,2))
plot(DMSO_comparison_model)

Interpretation

  • Looks like we may have issues with equal variance in the absence of DMSO.
  • Normality looks pretty good excpet for the 5th and 7th data points.
  1. Run formal tests to verify the assumptions of linear models.
#Run Breusch Pagan test for homoscedasticity
bptest(DMSO_comparison_model)

    studentized Breusch-Pagan test

data:  DMSO_comparison_model
BP = 2.9558, df = 1, p-value = 0.08557
#Run Shapir-Wilk normality test
shapiro.test(DMSO_comparison_model$residuals)

    Shapiro-Wilk normality test

data:  DMSO_comparison_model$residuals
W = 0.95749, p-value = 0.7569
#Run Durbin-Watson test for autocorrelation
dwtest(DMSO_comparison_model)

    Durbin-Watson test

data:  DMSO_comparison_model
DW = 1.4938, p-value = 0.2141
alternative hypothesis: true autocorrelation is greater than 0

Interpretation

studentized Breusch-Pagan test

data: DMSO_comparison_model BP = 6.5497, df = 3, p-value = 0.08557 p > 0.05 meaning we cannot reject the null hypothesis of homoscedasticity, this is good (just barely)

Shapiro-Wilk normality test

data: DMSO_comparison_model$residuals W = 0.72204, p-value = 0.7569 p >0.05, meaning we cannot reject the null hypothesis that are normally distributed.

Durbin-Watson test

data: DMSO_comparison_model DW = 1.9783, p-value = 0.2141

Alternative hypothesis: true autocorrelation is greater than 0 value is close to 2, no significant autocorrelation, p > 0.05 so we can’t reject null hypothesis of no autocorrelation

  1. Run the ANOVA and the Tukey comparison.
DMSO_type_III_ANOVA_results <- Anova(DMSO_comparison_model, type = 3)
DMSO_type_III_ANOVA_results
Anova Table (Type III tests)

Response: Cobalt_concentration_uM
                 Sum Sq Df F value    Pr(>F)    
(Intercept)    13940825  1  65.687 3.976e-05 ***
DMSO_treatment  6451314  1  30.398 0.0005648 ***
Residuals       1697852  8                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Interpretation

  • DMSO treatment had a significant effect on cobalt concentration at 168 hours for wild type cell experiments.
  1. Create a boxplot to illustrate this result. There is no need to annotate because there are only two boxes and the independent variable was significant.
theme<- theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), 
        panel.background = element_blank(), axis.line = element_line(colour = "black"),
        axis.text.x = element_text(color = "grey20", 
        size = 32, angle = 0, hjust = .5, vjust = .5, face = "plain"),
        axis.text.y = element_text(color = "grey20", 
        size = 32, angle = 0, hjust = 1, vjust = 0, face = "plain"),  
        axis.title.x = element_text(color = "grey20", 
        size = 34, angle = 0, hjust = .5, vjust = 0, face = "bold"),
        axis.title.y = element_text(color = "grey20", 
        size = 34, angle = 90, face = "bold"),
        strip.text.x = element_text(size = 32, colour = "grey20", face = "bold"),
        strip.text.y = element_text(size = 32, colour = "grey20"),
        plot.title = element_text(size = 30, face = "bold", hjust = .5),
        legend.title=element_text(size=32, face = "bold"), 
        legend.text=element_text(size=32),
        panel.border = element_rect(colour = "black", fill=NA, size=1))

DMSO_boxplot <- DMSO_comparison_data %>%
                ggplot(aes(x=DMSO_treatment, y=Cobalt_concentration_uM)) + 
                geom_boxplot() +
                geom_jitter(fill = "grey", colour = "black", width = 0.1, pch =21, stroke =1)+
                ylim(0, 3000) +
                labs(title = "" ,
                y = "Cobalt\nconcentration (µM)", 
                x = "DMSO treatment") +
                theme +
                theme(plot.margin = unit(c(1,1,1,1), "cm"),
                      axis.title.x = element_text(vjust = -2),
                      axis.title.y = element_text(vjust = 2),
                      axis.text.x = element_text(angle = 0))

DMSO_boxplot

#Save different image formats
ggsave("FigS14_cobalt_ICPMS_data_DMSO.jpg", dpi = 300, height=8, width=10, device=jpeg)
ggsave("FigS14_cobalt_ICPMS_data_DMSO.tiff", dpi = 300, height=8, width=10, device=tiff)
ggsave("FigS14_cobalt_ICPMS_data_DMSO.pdf", dpi = 300, height=8, width=10, device=cairo_pdf)

#Bioinformatics analyses of genome annotations generated using DRAM

Run DRAM for annotations and distillation

  1. Activate the conda environment containing DRAM and run the annotate command. Replace the directory and fasta file with the genome file for Pseudomonas chlororaphis subspecies aurefoaciens (or any genome or genoems of your choice)
DRAM.py annotate -i 'Pseudomonas_genome_analyses/*.fasta' --use_uniref -o Pseudomonas_annotation_with_uniref --threads 8
  1. Once the annotation is complete, use the distillation command. Make sure to use the same output directory from the annotate step.
DRAM.py distill -i Pseudomonas_annotation_with_uniref/annotations.tsv -o Pseudomonas_genome_summaries --trna_path Pseudomonas_annotation_with_uniref/trnas.tsv --rrna_path Pseudomonas_annotation_with_uniref/rrnas.tsv

Manually search for cobalt genes in the annotation output by DRAM

  1. Load in the tab-delimited file containing the annotation data.
Pseudomonas_chlororaphis_aureofaciens_annotations <- fread("Pseudomonas_chlororaphis_aureofaciens_DRAM_annotations.tsv", sep = "\t", header = "auto")
  1. Manually search the annotation file using different strings of test for functions relevant to cobalt and microbially-induced corrosion.
corrosion_pathways <- Pseudomonas_chlororaphis_aureofaciens_annotations %>%
                    
                   #Simple text search for "cobalt"
                   filter(
                     (if_any(c(kegg_hit:pfam_hits), ~ grepl("cobalt", .))) |
                     (if_any(c(kegg_hit:pfam_hits), ~ grepl("cob", .))) |
                     (if_any(c(kegg_hit:pfam_hits), ~ grepl("cyanide", .)))|
                     (if_any(c(kegg_hit:pfam_hits), ~ grepl("hcn", .)))|
                     (if_any(c(kegg_hit:pfam_hits), ~ grepl("cytochrome", .)))|
                     #(if_any(c(kegg_hit:pfam_hits), ~ grepl("hydrogenase", .)))| this is non-specific and picks up anything with dehydrogenase, comment out
                     (if_any(c(kegg_hit:pfam_hits), ~ grepl("siderophore", .)))) %>%
                    dplyr::select(scaffold,
                           gene_position,
                           start_position,
                           end_position,
                           ko_id,
                           kegg_hit,
                           uniref_id,
                           uniref_hit)

#Write the table to save the source data
write.table(corrosion_pathways, file = "SuppData_Pseudomonas_chlororaphis_aureofaciens_putative_corrosion_pathways.tsv", sep = "\t", row.names = FALSE)

Summary of key antiSMASH biosynthetic gene cluster regions

key biosynthetic genes are denoted by asterisks in markdown format.

Region 2 (hydrogen cyanide cluster): 2951483 to 2964455

Region2 <- Pseudomonas_chlororaphis_aureofaciens_annotations %>% filter(start_position >= 2951483 & end_position <=2964455)

Genes in hydrogen cyanide-cluster: - ctg1_2591: 2956483 - 2956800 –> hydrogen cyanide synthase HcnA [EC:1.4.99.5] (C grade, KEGG ID = K10814) - ctg1_2592: 2956797 - 2958206 –> hydrogen cyanide synthase HcnB [EC:1.4.99.5] (B grade, KEGG ID = K10815) - ctg1_2593: 2958199 - 2959455 –> hydrogen cyanide synthase HcnC [EC:1.4.99.5] (B grade, KEGG ID = K10816) - ctg1_2594: 2959618 - 2960223 –> glutathione S-transferase [EC:2.5.1.18] (B grade, KEGG ID = K00799)

Region 6 (NI-siderophore): 3832837 to 3869821

Region6 <- Pseudomonas_chlororaphis_aureofaciens_annotations %>% filter(start_position >= 3832837 & end_position <=3869821)

Genes in NI-siderophore cluster:

  • ctg1_3372: 3846837 - 3848735 –> staphyloferrin B synthase [EC:6.3.2.56] (B grade KEGG ID = K23375)
  • ctg1_3373: 3848740 - 3849513 –> staphyloferrin B biosynthesis citrate synthase (B grade, KEGG ID = K23376)
  • ctg1_3374: 3849507 - 3851369 –> 2-[(L-alanin-3-ylcarbamoyl)methyl]-3-(2-aminoethylcarbamoyl)-2-hydroxypropanoate synthase [EC:6.3.2.55] (B grade, KEGG ID = K23374)
  • ctg1_3375: 3851394 - 3852812 –> UniRef90_A0A554P7Y5 DHA2 family efflux MFS transporter permease subunit n=30 Tax=Pseudomonadaceae TaxID=135621 RepID=A0A554P7Y5_9PSED (B grade, no hit in KEGG)
  • ctg1_3376: 3852809 - 3854029 –> diaminopimelate decarboxylase [EC:4.1.1.20] (B grade, KEGG ID = K01586)
  • ctg1_3377: 3854022 - 3855821 –> UniRef90_A0A0C5EL69 AcsD protein n=70 Tax=Pseudomonadaceae TaxID=135621 RepID=A0A0C5EL69_9PSED (B grade, no hit in KEGG)

Region 7 (hydrogen cyanide cluster): 3888854 to 3901701

Region7 <- Pseudomonas_chlororaphis_aureofaciens_annotations %>% filter(start_position >= 3888854 & end_position <=3901701)
  • ctg1_3405: 3890984 - 3892441 –> succinate-semialdehyde dehydrogenase / glutarate-semialdehyde dehydrogenase [EC:1.2.1.16 1.2.1.79 1.2.1.20] (B grade, KEGG ID = K00135)
  • ctg1_3406: 3892700 - 3893857 –> acetylornithine deacetylase [EC:3.5.1.16] (B grade, KEGG ID = K01438)
  • ctg1_3407: 3893854 - 3895008 –> UniRef90_A0AA45XIN0 Sarcosine oxidase subunit beta n=5 Tax=Pseudomonas TaxID=286 RepID=A0AA45XIN0_9PSED (no KEGG hit, B grade, UniRef ID = A0AA45XIN0_9PSED)
    • Catalyzes oxidative demethylation of sarcosine (N-methylglycine) to yield glycine
  • ctg1_3408: 3895005 - 3896411 –> UniRef90_A0A3G7K0E2 Opine oxidase subunit A n=39 Tax=Pseudomonas TaxID=286 RepID=A0A3G7K0E2_9PSED, (no KEGG hit, B grade, Uniref ID = A0A3G7K0E2_9PSED)
    • Cleaves opines into amino acids and pyruvate
  • ctg1_3409: 3896393 - 3896701 –> UniRef90_A0A5M7CTD1 (2Fe-2S)-binding protein n=14 Tax=Pseudomonadaceae TaxID=135621 RepID=A0A5M7CTD1_9PSED (C grade, no KEGG hit, UniRef ID = A0A5M7CTD1_9PSED)
  • ctg1_3410: 3896698 - 3898539 –> peptide/nickel transport system ATP-binding protein (B grade, KEGG ID = K02031)
  • ctg1_3411: 3898541 - 3899416 –> UniRef90_A0A0C1ZSU6 DNA-directed RNA polymerase subunit alpha n=30 Tax=Pseudomonadaceae TaxID=135621 RepID=A0A0C1ZSU6_PSEFL (no KEGG hit, B grade, Uniref ID = A0A0C1ZSU6_PSEFL)
  • ctg1_3412: 3899413 - 3900369 –> peptide/nickel transport system permease protein (B grade, KEGG ID = K02033)

Region 10 (NRP-metallophore): 5056434 to 5155407

Region10 <- Pseudomonas_chlororaphis_aureofaciens_annotations %>% filter(start_position >= 5056434 & end_position <=5155407)
  • ctg1_4474: 5,076,434 - 5,077,768 –> L-ornithine N5-monooxygenase [EC:1.14.13.195 1.14.13.196] (B grade, KEGG ID = K10531)
  • ctg1_4475: 5,077,900 - 5,078,496 –> UniRef90_A0A165YGX4 RNA polymerase subunit sigma n=4 Tax=Pseudomonas TaxID=286 RepID=A0A165YGX4_PSEFL (C grade, no KEGG ID)
  • ctg1_4476: 5,078,716 - 5,079,888 –> membrane fusion protein, macrolide-specific efflux system (B grade, KEGG ID = K13888)
  • ctg1_4477: 5,079,889 - 5,081,862 –> macrolide transport system ATP-binding/permease protein [EC:7.6.2.-] (B grade, KEGG ID = K05685)
  • ctg1_4478: 5,081,870 - 5,083,279 –> outer membrane protein, multidrug efflux system (B grade, KEGG ID = K18139)
  • ctg1_4479: 5,083,355 - 5,084,977 –> UniRef90_A0A554PAC0 Twin-arginine translocation signal domain-containing protein n=19 Tax=Pseudomonadaceae TaxID=135621 RepID=A0A554PAC0_9PSED (B grade, no KEGG hit)
  • ctg1_4480: 5,085,186 - 5,086,595 –> membrane dipeptidase [EC:3.4.13.19] (B grade, KEGG ID = K01273)
  • ctg1_4481: 5,086,617 - 5,087,915 –> UniRef90_A0A2C9EQN1 Isopenicillin N epimerase CefD n=56 Tax=Pseudomonadaceae TaxID=135621 RepID=A0A2C9EQN1_PSEPH (B grade, no KEGG hit)
  • ctg1_4482: 5,087,959 - 5,088,855 –> UniRef90_Q4K997 Chromophore maturation protein PvdO n=55 Tax=Pseudomonadaceae TaxID=135621 RepID=Q4K997_PSEF5 (B grade, no KEGG hit)
  • ctg1_4483: 5,088,910 - 5,089,773 –> UniRef90_Q4K996 phosphoribosylglycinamide formyltransferase 1 n=49 Tax=Pseudomonadaceae TaxID=135621 RepID=Q4K996_PSEF5 (B grade, no KEGG hit)
  • ctg1_4484: 5,089,961 - 5,091,613 –> putative pyoverdin transport system ATP-binding/permease protein (B grade, KEGG ID = K06160)
  • ctg1_4485: 5,091,714 - 5,094,182 –> outer-membrane receptor for ferric coprogen and ferric-rhodotorulic acid (B grade, KEGG ID = K16088)
  • ctg1_4486: 5,094,570 - 5,107,805 –> UniRef90_A0A554PAB6 Amino acid adenylation domain-containing protein n=22 Tax=Pseudomonas TaxID=286 RepID=A0A554PAB6_9PSED (B grade, no KEGG hit)
  • ctg1_4487: 5,107,818 - 5,114,414 –> UniRef90_A0A554PAC2 Non-ribosomal peptide synthetase n=26 Tax=Pseudomonas TaxID=286 RepID=A0A554PAC2_9PSED (B grade, no KEGG hit)
  • ctg1_4488: 5,114,414 - 5,125,576 –> UniRef90_UPI002407C9DD amino acid adenylation domain-containing protein n=4 Tax=Pseudomonas chlororaphis TaxID=587753 RepID=UPI002407C9DD (B grade, no KEGG hit)

Region 11 (NRPS): 5189456 to 5242472

Region11 <- Pseudomonas_chlororaphis_aureofaciens_annotations %>% filter(start_position >= 5189456 & end_position <=5242472)

NRPS region here is really only one gene: - ctg1_4563: 5209456 - 5222472 –> UniRef90_A0A554PEL7 Non-ribosomal peptide synthetase n=29 Tax=Pseudomonadaceae TaxID=135621 RepID=A0A554PEL7_9PSED (B grade, no KEGG hit)

LS0tCnRpdGxlOiAiQ29iYWx0IGNvcnJvc2lvbiBHaXRodWIgY29kZWJvb2siCm91dHB1dDogaHRtbF9ub3RlYm9vawplZGl0b3Jfb3B0aW9uczogCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCiMgVGFibGUgb2YgY29udGVudHMKCi0gRmlndXJlIDE6IENvYmFsdCBjb3Jyb3Npb24gZGF0YSBmb3Igd2lsZCB0eXBlIGNlbGxzLCDiiIZwaHogbXV0YW50cywgc3BlbnQgbWVkaXVtLCBhbmQgYWJpb3RpYyBjb250cm9scyBpbiBzdGVyaWxlIG1lZGl1bSAoKmRvbmUqKQotIEZpZ3VyZSBTMTogQU5PVkEgdGVzdCBvbiBjb2JhbHQgY29uY2VudHJhdGlvbnMgc2FtcGxlZCBhdCAxNjggaG91cnMgaW4gYmlvdGljIHZzIGFiaW90aWMgdHJlYXRtZW50cyB3aXRoIGFuZCB3aXRob3V0IG1hc3MgYmFsYW5jZSBjb3JyZWN0aW9uICgqZG9uZSopCi0gRmlndXJlIFMyOiBBTk9WQSB0ZXN0IG9uIGFiaW90aWMgY29udHJvbHMgd2l0aCBhbmQgd2l0aG91dCBwaGVuYXppbmUtMS1jYXJib3h5bGljIGFjaWQgKCpkb25lKikKLSBGaWd1cmUgMjogUGhlbmF6aW5lIG1ldGFib2xpdGUgY29uY2VudHJhdGlvbnMgbWVhc3VyZWQgdmlhIExDLUhSTVMgKGRvbmUpCi0gRmlndXJlIDM6IFdpbGQgdHlwZSB2cyDiiIZwaHogbXV0YW50IGNlbGwgZ3Jvd3RoIGluIGNvcnJvc2lvbiBhc3NheXMgKGRvbmUpCi0gRmlndXJlIFM1OiBDb2JhbHQgY29uY2VudHJhdGlvbnMgZm9yIHdpbGQgdHlwZSBjZWxscyB0aGF0IHdlcmUgYWNpZGlmaWVkIHRoZW4gZmlsdGVyZWQsIG9yIGZpbHRlcmVkIHRoZW4gYWNpZGlmaWVkIChkb25lKQotIEZpZ3VyZSBTNi4gRG9zZSByZXNwb25zZSBjdXJ2ZXMgZm9yIHdpbGQgdHlwZSBjZWxsIGdyb3d0aCByYXRlIGFzIGEgZnVuY3Rpb24gb2YgY29iYWx0IGNvbmNlbnRyYXRpb24gKGRvbmUpCi0gRmlndXJlIFMxNDogQU5PVkEgdGVzdCBvbiBsaXZlIGNlbGxzIHdpdGggYW5kIHdpdGhvdXQgRE1TTwotIEJpb2luZm9ybWF0aWNzIGFuYWx5c2VzIG9mIGdlbm9tZSBhbm5vdGF0aW9ucyBnZW5lcmF0ZWQgd2l0aCBEUkFNCgojIFBhY2thZ2VzIHJlcXVpcmVkCgpMb2FkIGFsbCBvZiB0aGVzZSBwYWNrYWdlcyBiZWZvcmUgcnVubmluZyBhbnkgb2YgdGhlIGNodW5rcyBvZiBjb2RlIGluIHRoZSBzdWJzZWN0aW9ucyBiZWxvdy4KYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHJlYWR4bCkKbGlicmFyeShkYXRhLnRhYmxlKQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShDYWlybykKbGlicmFyeShsbXRlc3QpCmxpYnJhcnkoY2FyKQpsaWJyYXJ5KHdlc2FuZGVyc29uKQpsaWJyYXJ5KGdnYnJlYWspCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KGdnaDR4KQpsaWJyYXJ5KGdndGV4dCkKbGlicmFyeShkcmMpCmBgYAoKIyBGaWd1cmUgMTogQ29iYWx0IGNvcnJvc2lvbiBkYXRhIGZvciB3aWxkIHR5cGUgY2VsbHMsIOKIhnBoeiBtdXRhbnRzLCBzcGVudCBtZWRpdW0sIGFuZCBhYmlvdGljIGNvbnRyb2xzIGluIHN0ZXJpbGUgbWVkaXVtCgoxLiBVc2UgdGhlIGNvZGUgYmVsb3cgdG8gbG9hZCBpbiBzb3VyY2UgZGF0YS4KYGBge3J9CkFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCA8LSBmcmVhZCgiQWxsX2NvYmFsdF9JQ1BNU19kYXRhX2NsZWFuZWRfZm9ybWF0dGVkXzIwMjUwNTEzLnR4dCIsIHNlcCA9ICJcdCIsIGhlYWRlciA9ICJhdXRvIikKYGBgCgoyLiBVc2UgdGhlIGNvZGUgYmVsb3cgdG8gZ2VuZXJhdGUgdGhlIHNjYXR0ZXJwbG90IGNvbnRhaW5pbmcgdGhlIGNhdGVnb3JpZXMgb2YgaW50ZXJlc3QuCmBgYHtyfQojQWRqdXN0IHRoZSBwcmVzZW50YXRpb24gYWVzdGhldGljcwp0aGVtZTwtIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCAKICAgICAgICBzaXplID0gMzIsIGFuZ2xlID0gMCwgaGp1c3QgPSAuNSwgdmp1c3QgPSAuNSwgZmFjZSA9ICJwbGFpbiIpLAogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIAogICAgICAgIHNpemUgPSAzMiwgYW5nbGUgPSAwLCBoanVzdCA9IDEsIHZqdXN0ID0gMCwgZmFjZSA9ICJwbGFpbiIpLCAgCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIAogICAgICAgIHNpemUgPSAzNCwgYW5nbGUgPSAwLCBoanVzdCA9IC41LCB2anVzdCA9IDAsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCAKICAgICAgICBzaXplID0gMzQsIGFuZ2xlID0gOTAsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMzIsIGNvbG91ciA9ICJncmV5MjAiLCBmYWNlID0gImJvbGQiKSwKICAgICAgICBzdHJpcC50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDMyLCBjb2xvdXIgPSAiZ3JleTIwIiksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMzAsIGZhY2UgPSAiYm9sZCIsIGhqdXN0ID0gLjUpLAogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT0zMiwgZmFjZSA9ICJib2xkIiksIAogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTMyKSwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiwgZmlsbD1OQSwgc2l6ZT0xKSkKCiNDcmVhdGUgY3VzdG9tIGRpc3BsYXkgb3JkZXJzCkFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCRBYmlvdGljX3ZzX2Jpb3RpY19vcmRlcmVkIDwtIGZhY3RvcihBbGxfY29iYWx0X2RhdGFfY29tYmluZWQkQWJpb3RpY192c19iaW90aWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJXaWxkIHR5cGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAi4oiGcGh6IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNwZW50IG1lZGl1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdGVyaWxlIG1lZGl1bSIpKQoKQWxsX2NvYmFsdF9kYXRhX2NvbWJpbmVkJE1ldGFib2xpdGVfdHJlYXRtZW50X29yZGVyZWQgPC0gZmFjdG9yKEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCRNZXRhYm9saXRlX3RyZWF0bWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJOb3RoaW5nIGFkZGVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQQ0EiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1lT0giKSkKI0dyYXBoaW5nIHNjcmlwdCB3aXRoIGFkZGl0aW9uYWwgZGF0YSBtYW5pcHVsYXRpb24KbGlicmFyeSh3ZXNhbmRlcnNvbikKQWJpb3RpY192c19iaW90aWNfdHJlYXRtZW50X3NjYXR0ZXJwbG90IDwtIEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihETVNPX3RyZWF0bWVudCA9PSAiTm8gRE1TTyIpICU+JSAjdXNlIHRoaXMgdG8gb25seSBmb2N1cyBvbiBleHBlcmltZW50cyB0aGF0IGRpZCBub3QgcmVjZWl2ZSBETVNPCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoU2FtcGxlX3ByZXNlcnZhdGlvbiA9PSAiQWNpZGlmaWVkLCBmaWx0ZXJlZCIpICU+JSAjMjE2IG9ic2VydmF0aW9ucwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoQWJpb3RpY192c19iaW90aWMsIFdpcmVfdHJlYXRtZW50LCBETVNPX3RyZWF0bWVudCwgTWV0YWJvbGl0ZV90cmVhdG1lbnQsIFRpbWUpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lYW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdWdfTCA9IG1lYW4oQ29iYWx0X2NvbmNlbnRyYXRpb25fdWdfTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVkaWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wgPSBtZWRpYW4oQ29iYWx0X2NvbmNlbnRyYXRpb25fdWdfTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RkZXZfY29iYWx0X2NvbmNlbnRyYXRpb25fdWdfTCA9IHNkKENvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1pbl9jb2JhbHRfY29uY2VudHJhdGlvbl91Z19MID0gbWluKENvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1heF9jb2JhbHRfY29uY2VudHJhdGlvbl91Z19MID0gbWF4KENvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lYW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdU0gPSBtZWFuKENvYmFsdF9jb25jZW50cmF0aW9uX3VNKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZWRpYW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdU0gPSBtZWRpYW4oQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0ZGV2X2NvYmFsdF9jb25jZW50cmF0aW9uX3VNID0gc2QoQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1pbl9jb2JhbHRfY29uY2VudHJhdGlvbl91TSA9IG1pbihDb2JhbHRfY29uY2VudHJhdGlvbl91TSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF4X2NvYmFsdF9jb25jZW50cmF0aW9uX3VNID0gbWF4KENvYmFsdF9jb25jZW50cmF0aW9uX3VNKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxvY2F0ZShNZWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VnX0w6TWF4X2NvYmFsdF9jb25jZW50cmF0aW9uX3VNLCAuYWZ0ZXIgPSBDb2JhbHRfY29uY2VudHJhdGlvbl91TSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIUJvdHRsZV9udW1iZXIgPT0gIjEiKSAlPiUgI3JlbW92ZSBvdXRsaWVyIHN0ZXJpbGUgY29udHJvbAoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI3Bsb3R0aW5nIHNjcmlwdAogICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdChhZXMoeD1UaW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IE1lYW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdU0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBBYmlvdGljX3ZzX2Jpb3RpY19vcmRlcmVkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGUgPSBNZXRhYm9saXRlX3RyZWF0bWVudF9vcmRlcmVkKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fcG9pbnQoc2l6ZSA9IDYpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbl9jb2JhbHRfY29uY2VudHJhdGlvbl91TSAtIFN0ZGV2X2NvYmFsdF9jb25jZW50cmF0aW9uX3VNLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHltYXggPSBNZWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VNICsgU3RkZXZfY29iYWx0X2NvbmNlbnRyYXRpb25fdU0pKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKGFlcyhncm91cCA9IEJvdHRsZV9udW1iZXIsIGNvbG9yID0gQWJpb3RpY192c19iaW90aWNfb3JkZXJlZCkpKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTY4LCBieSA9IDI0KSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2V0X2dyaWQofiBXaXJlX3RyZWF0bWVudCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWIoIkNvYmFsdFxuY29uY2VudHJhdGlvbiAowrVNKSIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bGFiKCJUaW1lIGVsYXBzZWQgKGhvdXJzKSIpICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiQWJpb3RpYyB2cyBiaW90aWMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcxIiwgbiA9IDQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJXaWxkIHR5cGUiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbihpdGFsaWMoIuKIhnBoeiIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNwZW50IG1lZGl1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdGVyaWxlIG1lZGl1bSIpKSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZV9zaGFwZV9kaXNjcmV0ZShuYW1lID0gIk1ldGFib2xpdGUgdHJlYXRtZW50IikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gLTIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDIpKQogICAgICAgICAgCiNBZGQgYSBsYXllciB0byBhbmdsZSB0aGUgdGV4dApBYmlvdGljX3ZzX2Jpb3RpY190cmVhdG1lbnRfc2NhdHRlcnBsb3RfYW5nbGVkIDwtIEFiaW90aWNfdnNfYmlvdGljX3RyZWF0bWVudF9zY2F0dGVycGxvdCArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKQoKI1NhdmUgaW4gZGlmZmVyZW50IGltYWdlIGZvcm1hdHMgYXQgMzAwIGRwaQpnZ3NhdmUoIkZpZzFfQ29iYWx0X0lDUE1TX2RhdGFfYWJpb3RpY19iaW90aWNfYW5kX21ldGFib2xpdGVfdHJlYXRtZW50c19ub19ETVNPX3NjYXR0ZXJwbG90X2FuZ2xlZC5qcGciLCBkcGkgPSAzMDAsIGhlaWdodD04LCB3aWR0aD0yMiwgZGV2aWNlPSBqcGVnKQpnZ3NhdmUoIkZpZzFfQ29iYWx0X0lDUE1TX2RhdGFfYWJpb3RpY19iaW90aWNfYW5kX21ldGFib2xpdGVfdHJlYXRtZW50c19ub19ETVNPX3NjYXR0ZXJwbG90X2FuZ2xlZC50aWZmIiwgZHBpID0gMzAwLCBoZWlnaHQ9OCwgd2lkdGg9MjIsIGRldmljZT0gdGlmZikKZ2dzYXZlKCJGaWcxX0NvYmFsdF9JQ1BNU19kYXRhX2FiaW90aWNfYmlvdGljX2FuZF9tZXRhYm9saXRlX3RyZWF0bWVudHNfbm9fRE1TT19zY2F0dGVycGxvdF9hbmdsZWQucGRmIiwgZHBpID0gMzAwLCBoZWlnaHQ9OCwgd2lkdGg9MjIsIGRldmljZT0gY2Fpcm9fcGRmKQpgYGAKCgojIEZpZ3VyZSBTMTogQU5PVkEgdGVzdCBvbiBjb2JhbHQgY29uY2VudHJhdGlvbnMgc2FtcGxlZCBhdCAxNjggaG91cnMgaW4gYmlvdGljIHZzIGFiaW90aWMgdHJlYXRtZW50cyB3aXRoIGFuZCB3aXRob3V0IG1hc3MgYmFsYW5jZSBjb3JyZWN0aW9uCgojIyBGaWd1cmUgUzFBOiBBTk9WQSB0ZXN0IHdpdGhvdXQgcmVjb3ZlcmllcyBhcHBsaWVkCgoxLiBMb2FkIHRoZSBjb2JhbHQgZGF0YSBhbmQgdHJpbSBpdCB3aGVyZSB0aGUgd2lyZSB3YXMgc3VwcGxpZWQuCmBgYHtyfQpBbGxfY29iYWx0X2RhdGFfY29tYmluZWQgPC0gZnJlYWQoIkFsbF9jb2JhbHRfSUNQTVNfZGF0YV9jbGVhbmVkX2Zvcm1hdHRlZF8yMDI1MDUxMy50eHQiLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSAiYXV0byIpCgpBYmlvdGljX3ZzX2Jpb3RpY193aXJlX29ubHlfQU5PVkFfZGF0YSA8LSBBbGxfY29iYWx0X2RhdGFfY29tYmluZWQgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihETVNPX3RyZWF0bWVudCA9PSAiTm8gRE1TTyIpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFNhbXBsZV9wcmVzZXJ2YXRpb24gPT0gIkFjaWRpZmllZCwgZmlsdGVyZWQiKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihUaW1lID09IDE2OCkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihNZXRhYm9saXRlX3RyZWF0bWVudCA9PSAiTm90aGluZyBhZGRlZCIpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoV2lyZV90cmVhdG1lbnQgPT0gIldpcmUgaW5jbHVkZWQiKSAjMjQgb2JzZXJ2YXRpb25zCmBgYAoKMi4gR2VuZXJhdGUgdGhlIEFOT1ZBIG1vZGVsIHdpdGggdHlwZSBJSUkgc3VtIG9mIHNxdWFyZXMgdG8gYWNjb3VudCBmb3IgdGhlIHVuYmFsYW5jZWQgZGVzaWduIGFuZCBpbnRlcnByZXQgdmlzdWFsaXphdGlvbnMgZm9yIGxpbmVhciBtb2RlbCBhc3N1bXB0aW9ucwpgYGB7cn0KQWJpb3RpY192c19iaW90aWNfbW9kZWwgPC0gbG0oQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0gfiBBYmlvdGljX3ZzX2Jpb3RpYywgZGF0YSA9IEFiaW90aWNfdnNfYmlvdGljX3dpcmVfb25seV9BTk9WQV9kYXRhLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJhc3RzID0gbGlzdChBYmlvdGljX3ZzX2Jpb3RpYyA9IGNvbnRyLnN1bSksIHR5cGUgPTMpCgpBYmlvdGljX3ZzX2Jpb3RpY19tb2RlbApwYXIobWZyb3cgPSBjKDIsMikpCnBsb3QoQWJpb3RpY192c19iaW90aWNfbW9kZWwpCgojUnVuIEJyZXVzY2ggUGFnYW4gdGVzdCBmb3IgaG9tb3NjZWRhc3RpY2l0eQpicHRlc3QoQWJpb3RpY192c19iaW90aWNfbW9kZWwpCgojUnVuIFNoYXBpcm8tV2lsayBub3JtYWxpdHkgdGVzdApzaGFwaXJvLnRlc3QoQWJpb3RpY192c19iaW90aWNfbW9kZWwkcmVzaWR1YWxzKQoKI1J1biBEdXJiaW4tV2F0c29uIHRlc3QgZm9yIGF1dG9jb3JyZWxhdGlvbgpkd3Rlc3QoQWJpb3RpY192c19iaW90aWNfbW9kZWwpCmBgYAoKIyMjIEludGVycHJldGF0aW9uCi0gSG9tb3NjZWRhc3RpY2l0eSBsb29rcyBsaWtlIGl0IG1heSBiZSBhIHNsaWdodCBpc3N1ZSBlc3BlY2lhbGx5IGFzIGNvYmFsdCBjb25jZW50cmF0aW9ucyBnZXQgaGlnaGVyLgotIFRoZXJlIGFyZSBhIGZldyBzbGlnaHRseSBwcm9ibGVtYXRpYyB2YWx1ZXMgb24gdGhlIFEtUSByZXNpZHVhbHMgcGxvdCB0aGF0IG1heSBuZWVkIHRvIGJlIGFkZHJlc3NlZCB3aXRoIGEgbG9nIHRyYW5zZm9ybSAodmFsdWUgNiBpbiBwYXJ0aWN1bGFyKS4KLSBCUCB0ZXN0IHJldHVybnMgYSBwLXZhbHVlIG9mICowLjAzOTczKiwgc28gd2UgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgb2YgaG9tb3NjZWRhc3RpY2l0eSAoYXMgZXhwZWN0ZWQpLgotIFNXIHRlc3QgcmV0dXJucyBhIHAtdmFsdWUgb2YgKjAuMzUxNiosIHNvIHdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHJlc2lkdWFscyBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuCi0gRFcgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAqMC4zMjk1Kiwgc28gd2UgY2Fubm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgdGhlcmUgaXMgbm8gYXV0b2NvcnJlbGF0aW9uIGJldHdlZW4gZGF0YSBwb2ludHMuCgoyLiBSZS1ydW4gdGhlIG1vZGVsIHdpdGggYSBsb2cxMCB0cmFuc2Zvcm0gdG8gYWRkcmVzcyB0aGUgaXNzdWVzIGFzc29jaWF0ZWQgd2l0aCBob21vc2NlZGFzdGljaXR5LgpgYGB7cn0KQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTAgPC0gbG0obG9nMTAoQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pIH4gQWJpb3RpY192c19iaW90aWMsIGRhdGEgPSBBYmlvdGljX3ZzX2Jpb3RpY193aXJlX29ubHlfQU5PVkFfZGF0YSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyYXN0cyA9IGxpc3QoQWJpb3RpY192c19iaW90aWMgPSBjb250ci5zdW0pLCB0eXBlID0zKQoKQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTAKcGFyKG1mcm93ID0gYygyLDIpKQpwbG90KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwKQoKI1J1biBCcmV1c2NoIFBhZ2FuIHRlc3QgZm9yIGhvbW9zY2VkYXN0aWNpdHkKYnB0ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwKQoKI1J1biBTaGFwaXJvLVdpbGsgbm9ybWFsaXR5IHRlc3QKc2hhcGlyby50ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwJHJlc2lkdWFscykKCiNSdW4gRHVyYmluLVdhdHNvbiB0ZXN0IGZvciBhdXRvY29ycmVsYXRpb24KZHd0ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwKQpgYGAKIyMjIEludGVycHJldGF0aW9uCi0gSG9tb3NjZWRhc3RpY2l0eSBsb29rcyBsaWtlIGl0IHdpa2xsIGJlIGxlc3Mgb2YgYW4gaXNzdWUsIGFsdGhvdWdoIG5vdyB2YWx1ZSBwb2ludCAxLCB0aGUgb3V0bGllciwgaXMgcHJvYmxlbWF0aWMuCi0gQlAgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAqMC40MjE3Kiwgc28gd2UgY2Fubm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIG9mIGhvbW9zY2VkYXN0aWNpdHkuCi0gU1cgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAqMC4wNDcyNSosIHNvIHdlIHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgcmVzaWR1YWxzIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZC4KLSBEVyB0ZXN0IHJldHVybnMgYSBwLXZhbHVlIG9mICowLjA3MzYqLCBzbyB3ZSBjYW5ub3QgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGVyZSBpcyBubyBhdXRvY29ycmVsYXRpb24gYmV0d2VlbiBkYXRhIHBvaW50cy4KClRoZSBpc3N1ZSB3aXRoIHRoZSBwb3RlbnRpYWwgb3V0bGllciBpcyBiYWNrLiBUaGlzIHdhcyBhIGNvbnRhbWluYXRlZCBzdGVyaWxlIGNvbnRyb2wsIHNvIHRoZXJlIGlzIGEgKmJpb2xvZ2ljYWwqIHJlYXNvbiB0byByZW1vdmUgaXQgZnJvbSBjb25zaWRlcmF0aW9uLgoKMy4gUmUtcnVuIHRoZSBtb2RlbCByZW1vdmluZyB0aGUgb3V0bGllciBhbmQgdGhlbiBsb2cxMC10cmFuc2Zvcm1pbmcgdGhlIGRhdGEgdG8gYWRkcmVzcyBpc3N1ZXMgb2Ygbm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiByZXNpZHVhbHMuCmBgYHtyfQpBYmlvdGljX3ZzX2Jpb3RpY193aXJlX29ubHlfQU5PVkFfZGF0YV9vdXRsaWVyX3JlbW92ZWQgPC0gQWxsX2NvYmFsdF9kYXRhX2NvbWJpbmVkICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKERNU09fdHJlYXRtZW50ID09ICJObyBETVNPIikgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFNhbXBsZV9wcmVzZXJ2YXRpb24gPT0gIkFjaWRpZmllZCwgZmlsdGVyZWQiKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoVGltZSA9PSAxNjgpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKE1ldGFib2xpdGVfdHJlYXRtZW50ID09ICJOb3RoaW5nIGFkZGVkIikgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoV2lyZV90cmVhdG1lbnQgPT0gIldpcmUgaW5jbHVkZWQiKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcighU2FtcGxlX25hbWUgPT0gIjIwMjQtMDItMjBfMTY4aHJfV2lyZStNZWRpYV8xX0EtRiIpICNzdXNwZWN0ZWQgb3V0bGllcgoKIyNHZW5lcmF0ZSBtb2RlbApBYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWQgPC0gbG0obG9nMTAoQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pIH4gQWJpb3RpY192c19iaW90aWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IEFiaW90aWNfdnNfYmlvdGljX3dpcmVfb25seV9BTk9WQV9kYXRhX291dGxpZXJfcmVtb3ZlZCAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJhc3RzID0gbGlzdChBYmlvdGljX3ZzX2Jpb3RpYyA9IGNvbnRyLnN1bSksIHR5cGUgPTMpCgpBYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWQKcGFyKG1mcm93ID0gYygyLDIpKQpwbG90KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZCkKCiNSdW4gQnJldXNjaCBQYWdhbiB0ZXN0IGZvciBob21vc2NlZGFzdGljaXR5CmJwdGVzdChBYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWQpCgojUnVuIFNoYXBpcm8tV2lsayBub3JtYWxpdHkgdGVzdApzaGFwaXJvLnRlc3QoQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkJHJlc2lkdWFscykKCiNSdW4gRHVyYmluLVdhdHNvbiB0ZXN0IGZvciBhdXRvY29ycmVsYXRpb24KZHd0ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZCkKYGBgCgojIyMgSW50ZXJwcmV0YXRpb24KLSBIb21vc2NlZGFzdGljaXR5IGxvb2tzIG9rYXkgYXMgZG9lcyB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiBvZiByZXNpZHVhbHMuCi0gQlAgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAwLjQzNTUsIHNvIHdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBvZiBob21vc2NlZGFzdGljaXR5LgotIFNXIHRlc3QgcmV0dXJucyBhIHAtdmFsdWUgb2YgMC43NzUxLCBzbyB3ZSBjYW5ub3QgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCByZXNpZHVhbHMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLgotIERXIHRlc3QgcmV0dXJucyBhIHAtdmFsdWUgb2YgMC4zMzk1LCBzbyB3ZSBjYW5ub3QgcmVqZWN0IHRoZSBudWxsIGh5cG90aGVzaXMgdGhhdCB0aGVyZSBpcyBubyBhdXRvY29ycmVsYXRpb24gYmV0d2VlbiBkYXRhIHBvaW50cy4KCioqQWxsIGxpbmVhciBtb2RlbCBhc3N1bXB0aW9ucyBhcmUgbWV0KioKCjQuIEdlbmVyYXRlIHRoZSBvdXRwdXQgb2YgYW5vdmEgbW9kZWwgZ2VuZXJhdGVkIHdpdGggdGhlIGRhdGEgd2hlcmUgdGhlIG91dGxpZXIgcmVtb3ZlZCBhbmQgYSBsb2cxMCB0cmFuc2Zvcm1hdGlvbiB3YXMgYXBwbGllZC4gVGhpcyBpcyByZXR1cm5pbmcgYSB0eXBlIDIgc3VtIG9mIHNxdWFyZXMgYmVjYXVzZSB3ZSBhcmUgbm8gbG9uZ2VyIGNvbnNpZGVyaW5nIHRoZSBpbnRlcmFjdGlvbiBoYXZpbmcgY29udHJvbGxlZCBmb3Igd2lyZSB0cmVhdG1lbnQKYGBge3J9CkFiaW90aWNfdnNfYmlvdGljX3R5cGVfSUlfQU5PVkFfcmVzdWx0cyA8LSBBbm92YShBYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWQsIHR5cGUgPSAzKQpBYmlvdGljX3ZzX2Jpb3RpY190eXBlX0lJX0FOT1ZBX3Jlc3VsdHMKYGBgCgojIyMgSW50ZXJwcmV0YXRpb24KLSBUaGVyZSBhcmUgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgaW4gY29iYWx0IGNvbmNlbnRyYXRpb24gYXQgMTY4IGhvdXJzIHRoYXQgYXJlIGF0dHJpYnV0YWJsZSB0byB0aGUgZGlmZmVyZW50IGFiaW90aWMgdnMgYmlvdGljIHRyZWF0bWVudHMuCgo1LiBSdW4gYSBUdWtleSBwb3N0LWhvYyB0ZXN0IHRvIGlkZW50aWZ5IHdoZXJlIHRoZSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBvY2N1ciBiZXR3ZWVuIHRyZWF0bWVudHMKYGBge3J9CiNGaXJzdCB5b3UgbmVlZCB0byBjb252ZXJ0IHRoZSBtb2RlbCB0byBhbiBhb3Ygb2JqZWN0CkFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9jb252ZXJ0ZWQgPC0gYW92KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZCkKVHVrZXlfY29tcGFyaXNvbl9hYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWQgPC0gVHVrZXlIU0QoQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkX2NvbnZlcnRlZCwgY29uZi5sZXZlbCA9IDAuOTUpClR1a2V5X2NvbXBhcmlzb25fYWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkClR1a2V5X2NvbXBhcmlzb25fYWJpb3RpY192c19iaW90aWNfZGF0YV9mcmFtZSA8LSBhcy5kYXRhLmZyYW1lKFR1a2V5X2NvbXBhcmlzb25fYWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkJEFiaW90aWNfdnNfYmlvdGljKQoKd3JpdGUudGFibGUoVHVrZXlfY29tcGFyaXNvbl9hYmlvdGljX3ZzX2Jpb3RpY19kYXRhX2ZyYW1lLCAKICAgICAgICAgICAgZmlsZSA9ICJUdWtleV9jb21wYXJpc29uX3Jlc3VsdHNfYWJpb3RpY192c19iaW90aWNfbG9nMTBfb3V0bGllcl9yZW1vdmVkXzIwMjUwNDAxLnR4dCIsIHNlcCA9ICJcdCIsIAogICAgICAgICAgICByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gVFJVRSkgCmBgYAoKIyMjIEludGVycHJldGF0aW9uCi0gVGhlcmUgYXJlIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGJldHdlZW46CiAgLSBTcGVudCBtZWRpdW0gdnMg4oiGcGh6CiAgLSBTdGVyaWxlIG1lZGl1bSB2cyDiiIZwaHoKICAtIFN0ZXJpbGUgbWVkaXVtIHZzIHNwZW50IG1lZGl1bQogIC0gV2lsZCB0eXBlIHZzIHNwZW50IG1lZGl1bQogIC0gV2lsZCB0eXBlIHZzIHN0ZXJpbGUgbWVkaXVtCi0gVGhlIG9ubHkgbm9uLXNpZ25pZmljYW50IGRpZmZlcmVuY2UgaXMgYmV0d2VlbiB3aWxkIHR5cGUgYW5kIOKIhnBoegotIExldHRlcnMgdG8gYWRkIHRvIHBsb3RzOgogIC0gV2lsZCB0eXBlOiBBCiAgLSDiiIZwaHo6IEEKICAtIFNwZW50IG1lZGl1bTogQgogIC0gU3RlcmlsZSBtZWRpdW06IEMKCjYuIEdlbmVyYXRlIGJveHBsb3RzIHRoYXQgd2lsbCBiZSB1c2VkIHRvIG92ZXJsYXkgdGhlIFR1a2V5IGFubm90YXRpb25zIG1hbnVhbGx5IGluIGFuIGltYWdlIGVkaXRvcgpgYGB7cn0KdGhlbWU8LSB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgc2l6ZSA9IDE2LCBhbmdsZSA9IDAsIGhqdXN0ID0gMC41LCB2anVzdCA9IDAsIGZhY2UgPSAicGxhaW4iKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCBzaXplID0gMTYsIGFuZ2xlID0gMCwgaGp1c3QgPSAwLjUsIHZqdXN0ID0gMCwgZmFjZSA9ICJwbGFpbiIpLCAgCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIHNpemUgPSAxOCwgYW5nbGUgPSAwLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAtMSwgZmFjZSA9ICJwbGFpbiIpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCBzaXplID0gMTgsIGFuZ2xlID0gOTAsIGZhY2UgPSAicGxhaW4iKSwKICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBjb2xvdXIgPSAiZ3JleTIwIiksCiAgICAgICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgY29sb3VyID0gImdyZXkyMCIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTgpLCAKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiwgZmlsbD1OQSwgc2l6ZT0xKSkKCiNDcmVhdGUgY3VzdG9tIG9yZGVyIHRvIGRpc3BsYXkgeC1heGlzCgpBbGxfY29iYWx0X2RhdGFfY29tYmluZWQkQWJpb3RpY192c19iaW90aWNfb3JkZXJlZCA8LSBmYWN0b3IoQWxsX2NvYmFsdF9kYXRhX2NvbWJpbmVkJEFiaW90aWNfdnNfYmlvdGljLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiV2lsZCB0eXBlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIuKIhnBoeiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTcGVudCBtZWRpdW0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3RlcmlsZSBtZWRpdW0iKSkKCkFiaW90aWNfdnNfYmlvdGljX3dpcmVfb25seV9ib3hwbG90X2xvZzEwIDwtIEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKERNU09fdHJlYXRtZW50ID09ICJObyBETVNPIikgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoU2FtcGxlX3ByZXNlcnZhdGlvbiA9PSAiQWNpZGlmaWVkLCBmaWx0ZXJlZCIpICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFRpbWUgPT0gMTY4KSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKE1ldGFib2xpdGVfdHJlYXRtZW50ID09ICJOb3RoaW5nIGFkZGVkIikgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihXaXJlX3RyZWF0bWVudCA9PSAiV2lyZSBpbmNsdWRlZCIpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIVNhbXBsZV9uYW1lID09ICIyMDI0LTAyLTIwXzE2OGhyX1dpcmUrTWVkaWFfMV9BLUYiKSAlPiUgI3N1c3BlY3RlZCBvdXRsaWVyCiAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjR3JhcGhpbmcgc2NyaXB0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdChhZXMoeD1BYmlvdGljX3ZzX2Jpb3RpY19vcmRlcmVkLCB5PWxvZzEwKENvYmFsdF9jb25jZW50cmF0aW9uX3VNKSkpICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fYm94cGxvdCgpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9qaXR0ZXIoZmlsbCA9ICJncmV5IiwgY29sb3VyID0gImJsYWNrIiwgd2lkdGggPSAwLjEsIHBjaCA9MjEsIHN0cm9rZSA9MSkrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsaW0oMCwgMy41KSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFicyh0aXRsZSA9ICIiICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gImxvZzEwKENvYmFsdCBjb25jZW50cmF0aW9uICjCtU0pKSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiQWJpb3RpYyBhbmQgYmlvdGljIHRyZWF0bWVudHMiKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lICsgI3RoaXMgY2FsbHMgdGhlIGFlc3RoZXRpYyB0aGVtZSB2YXJpYWJsZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IC0yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMikpCgpBYmlvdGljX3ZzX2Jpb3RpY193aXJlX29ubHlfYm94cGxvdF9sb2cxMCAjYW5vdGF0ZSB0aGlzIG1hbnVhbGx5IGluIGFuIGltYWdlIGVkaXRvcgoKI1NhdmUgZmlsZXMgaW4gZGlmZmVyZW50IGZvcm1hdHMKZ2dzYXZlKCJGaWdTMUFfQ29iYWx0X0lDUE1TX2RhdGFfYmlvdGljX3RyZWF0bWVudHNfbm9fRE1TT19ib3hwbG90X2xvZzEwXzIwMjUwNTE0LmpwZyIsIGRwaSA9IDMwMCwgaGVpZ2h0PTYsIHdpZHRoPTksIGRldmljZT0ganBlZykKZ2dzYXZlKCJGaWdTMUFfQ29iYWx0X0lDUE1TX2RhdGFfYmlvdGljX3RyZWF0bWVudHNfbm9fRE1TT19ib3hwbG90X2xvZzEwXzIwMjUwNTE0LnRpZmYiLCBkcGkgPSAzMDAsIGhlaWdodD02LCB3aWR0aD05LCBkZXZpY2U9IHRpZmYpCmdnc2F2ZSgiRmlnUzFBX0NvYmFsdF9JQ1BNU19kYXRhX2Jpb3RpY190cmVhdG1lbnRzX25vX0RNU09fYm94cGxvdF9sb2cxMF8yMDI1MDUxNC5wZGYiLCBkcGkgPSAzMDAsIGhlaWdodD02LCB3aWR0aD05LCBkZXZpY2U9Y2Fpcm9fcGRmKQpgYGAKCiMjIEZpZyBTMUI6IEFOT1ZBIHRlc3Qgd2l0aCBtYXNzIGJhbGFuY2UgcmVjb3ZlcmllcyBhcHBsaWVkCjEuIExvYWQgaW4gdGhlIGRhdGEgZnJvbSB0aGUgbWFudWFsbHkgYWRqdXN0ZWQgdGFiLWRlbGltaXRlZCBmaWxlIHRoYXQgY29udGFpbnMgcmVjb3Zlcmllcy4gR2VuZXJhdGUgYSBuZXcgdmFyaWFibGUgd2hlcmUgdGhlIHJlY292ZXJ5IGhhcyBiZWVuIGFwcGxpZWQuCmBgYHtyfQpBbGxfY29iYWx0X2RhdGFfY29tYmluZWRfcmVjb3ZlcmllcyA8LSBmcmVhZCgiQWxsX2NvYmFsdF9JQ1BNU19kYXRhX2NsZWFuZWRfZm9ybWF0dGVkXzIwMjUwNTEzLnR4dCIsIHNlcCA9ICJcdCIsIGhlYWRlciA9ICJhdXRvIikgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShDb2JhbHRfY29uY2VudHJhdGlvbl91TV9jb3JyZWN0ZWQgPSBDb2JhbHRfY29uY2VudHJhdGlvbl91TS9SZWNvdmVyeSkgJT4lICNhcHBseSByZWNvdmVyaWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbG9jYXRlKENvYmFsdF9jb25jZW50cmF0aW9uX3VNX2NvcnJlY3RlZCwgLmFmdGVyID0gQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pCmBgYAoKMi4gUnVuIHRoZSBtb2RlbCBhcHBseWluZyB0aGUgc2FtZSBvdXRsaWVyIHJlbW92YWwgYW5kIGxvZy10cmFuc2Zvcm1hdGlvbnMgdXNlZCBvbiB0aGUgZGF0YSB0aGF0IHdhcyBub3QgY29ycmVjdGVkIGZvciByZWNvdmVyeS4KYGBge3J9CkFiaW90aWNfdnNfYmlvdGljX3dpcmVfb25seV9BTk9WQV9kYXRhX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzIDwtIEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZF9yZWNvdmVyaWVzICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoRE1TT190cmVhdG1lbnQgPT0gIk5vIERNU08iKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihTYW1wbGVfcHJlc2VydmF0aW9uID09ICJBY2lkaWZpZWQsIGZpbHRlcmVkIikgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoVGltZSA9PSAxNjgpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoTWV0YWJvbGl0ZV90cmVhdG1lbnQgPT0gIk5vdGhpbmcgYWRkZWQiKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFdpcmVfdHJlYXRtZW50ID09ICJXaXJlIGluY2x1ZGVkIikgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcighU2FtcGxlX25hbWUgPT0gIjIwMjQtMDItMjBfMTY4aHJfV2lyZStNZWRpYV8xX0EtRiIpCgojI0dlbmVyYXRlIG1vZGVsCkFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzIDwtIGxtKGxvZzEwKENvYmFsdF9jb25jZW50cmF0aW9uX3VNX2NvcnJlY3RlZCkgfiBBYmlvdGljX3ZzX2Jpb3RpYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBBYmlvdGljX3ZzX2Jpb3RpY193aXJlX29ubHlfQU5PVkFfZGF0YV9vdXRsaWVyX3JlbW92ZWRfcmVjb3ZlcmllcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyYXN0cyA9IGxpc3QoQWJpb3RpY192c19iaW90aWMgPSBjb250ci5zdW0pLCB0eXBlID0zKQoKQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkX3JlY292ZXJpZXMKcGFyKG1mcm93ID0gYygyLDIpKQpwbG90KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzKQoKI1J1biBCcmV1c2NoIFBhZ2FuIHRlc3QgZm9yIGhvbW9zY2VkYXN0aWNpdHkKYnB0ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzKQoKI1J1biBTaGFwaXJvLVdpbGsgbm9ybWFsaXR5IHRlc3QKc2hhcGlyby50ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzJHJlc2lkdWFscykKCiNSdW4gRHVyYmluLVdhdHNvbiB0ZXN0IGZvciBhdXRvY29ycmVsYXRpb24KZHd0ZXN0KEFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzKQpgYGAKCiMjIyBJbnRlcnByZXRhdGlvbgotIEhvbW9zY2VkYXN0aWNpdHkgbG9va3Mgb2theSBhcyBkb2VzIHRoZSBub3JtYWwgZGlzdHJpYnV0aW9uIG9mIHJlc2lkdWFscy4KLSBCUCB0ZXN0IHJldHVybnMgYSBwLXZhbHVlIG9mIDAuNDM1NSwgc28gd2UgY2Fubm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIG9mIGhvbW9zY2VkYXN0aWNpdHkuCi0gU1cgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAwLjc3NTEsIHNvIHdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHJlc2lkdWFscyBhcmUgbm9ybWFsbHkgZGlzdHJpYnV0ZWQuCi0gRFcgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAwLjMzOTUsIHNvIHdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHRoZXJlIGlzIG5vIGF1dG9jb3JyZWxhdGlvbiBiZXR3ZWVuIGRhdGEgcG9pbnRzLgoKKipBbGwgbGluZWFyIG1vZGVsIGFzc3VtcHRpb25zIGFyZSBtZXQqKgoKMy4gR2VuZXJhdGUgdGhlIGFjdHVhbCBvdXRwdXQgb2YgYW5vdmEgbW9kZWwgZ2VuZXJhdGVkIHdpdGggdGhlIGRhdGEgd2hlcmUgdGhlIG91dGxpZXIgcmVtb3ZlZCBhbmQgYSBsb2cxMCB0cmFuc2Zvcm1hdGlvbiB3YXMgYXBwbGllZC4gVGhpcyBpcyByZXR1cm5pbmcgYSB0eXBlIDIgc3VtIG9mIHNxdWFyZXMgYmVjYXVzZSB3ZSBhcmUgbm90IGxvbmdlciBjb25zaWRlcmluZyB0aGUgaW50ZXJhY3Rpb24gaGF2aW5nIGNvbnRyb2xsZWQgZm9yIHdpcmUgdHJlYXRtZW50CmBgYHtyfQpBYmlvdGljX3ZzX2Jpb3RpY190eXBlX0lJX0FOT1ZBX3Jlc3VsdHNfcmVjb3ZlcmllcyA8LSBBbm92YShBYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWRfcmVjb3ZlcmllcywgdHlwZSA9IDMpCkFiaW90aWNfdnNfYmlvdGljX3R5cGVfSUlfQU5PVkFfcmVzdWx0c19yZWNvdmVyaWVzCmBgYAoKIyMjIEludGVycHJldGF0aW9uCi0gVGhlcmUgYXJlIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGluIGNvYmFsdCBjb25jZW50cmF0aW9uIGF0IDE2OCBob3VycyB0aGF0IGFyZSBhdHRyaWJ1dGFibGUgdG8gdGhlIGRpZmZlcmVudCBhYmlvdGljIHZzIGJpb3RpYyB0cmVhdG1lbnRzIGV2ZW4gYWZ0ZXIgY29ycmVjdGluZyBmb3IgcmVjb3Zlcmllcy4KLSBUaGUgcC12YWx1ZXMgYXJlIGRpZmZlcmVudCBmb3IgdGhlIHJlY292ZXJ5IGNvcnJlY3RlZCBkYXRhLCBidXQgYm90aCB2ZXJzaW9uIG9mIHRoZSBkYXRhIGhhdmUgcCA8IDAuMDAxLgoKNC4gUnVuIGEgVHVrZXkgcG9zdC1ob2MgdGVzdCB0byBmaWd1cmUgb3V0IHdoZXJlIHRoZSBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBhcmUuCmBgYHtyfQpsaWJyYXJ5KGRhdGEudGFibGUpCiNGaXJzdCB5b3UgbmVlZCB0byBjb252ZXJ0IHRoZSBtb2RlbCB0byBhbiBhb3Ygb2JqZWN0CkFiaW90aWNfdnNfYmlvdGljX21vZGVsX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9jb252ZXJ0ZWRfcmVjb3ZlcmllcyA8LSBhb3YoQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkX3JlY292ZXJpZXMpClR1a2V5X2NvbXBhcmlzb25fYWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkX3JlY292ZXJpZXMgPC0gVHVrZXlIU0QoQWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkX2NvbnZlcnRlZF9yZWNvdmVyaWVzLCBjb25mLmxldmVsID0gMC45NSkKVHVrZXlfY29tcGFyaXNvbl9hYmlvdGljX3ZzX2Jpb3RpY19tb2RlbF9sb2cxMF9vdXRsaWVyX3JlbW92ZWRfcmVjb3ZlcmllcwpUdWtleV9jb21wYXJpc29uX2FiaW90aWNfdnNfYmlvdGljX2RhdGFfZnJhbWVfcmVjb3ZlcmllcyA8LSBhcy5kYXRhLmZyYW1lKFR1a2V5X2NvbXBhcmlzb25fYWJpb3RpY192c19iaW90aWNfbW9kZWxfbG9nMTBfb3V0bGllcl9yZW1vdmVkX3JlY292ZXJpZXMkQWJpb3RpY192c19iaW90aWMpCgp3cml0ZS50YWJsZShUdWtleV9jb21wYXJpc29uX2FiaW90aWNfdnNfYmlvdGljX2RhdGFfZnJhbWVfcmVjb3ZlcmllcywgCiAgICAgICAgICAgIGZpbGUgPSAiVHVrZXlfY29tcGFyaXNvbl9yZXN1bHRzX2FiaW90aWNfdnNfYmlvdGljX2xvZzEwX291dGxpZXJfcmVtb3ZlZF9yZWNvdmVyaWVzXzIwMjUwNTEzLnR4dCIsIHNlcCA9ICJcdCIsIAogICAgICAgICAgICByb3cubmFtZXMgPSBGQUxTRSwgY29sLm5hbWVzID0gVFJVRSkgCmBgYAoKIyMjIEludGVycHJldGF0aW9uCi0gVGhlcmUgYXJlIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIGJldHdlZW46CiAgLSBTcGVudCBtZWRpdW0gdnMg4oiGcGh6CiAgLSBTdGVyaWxlIG1lZGl1bSB2cyDiiIZwaHoKICAtIFN0ZXJpbGUgbWVkaXVtIHZzIHNwZW50IG1lZGl1bQogIC0gV2lsZCB0eXBlIHZzIHNwZW50IG1lZGl1bQogIC0gV2lsZCB0eXBlIHZzIHN0ZXJpbGUgbWVkaXVtCi0gVGhlIG9ubHkgbm9uLXNpZ25pZmljYW50IGRpZmZlcmVuY2UgaXMgYmV0d2VlbiB3aWxkIHR5cGUgYW5kIOKIhnBoegotIEV4cGVjdGVkIGxldHRlcnMKICAtIFdpbGQgdHlwZTogQQogIC0g4oiGcGh6OiBBCiAgLSBTcGVudCBtZWRpdW06IEIKICAtIFN0ZXJpbGUgbWVkaXVtOiBDCgo1LiBSZWdlbmVyYXRlIGJveHBsb3RzIHRoYXQgd2lsbCBiZSB1c2VkIHRvIG92ZXJsYXkgdGhlIFR1a2V5IGFubm90YXRpb25zIG1hbnVhbGx5LgpgYGB7cn0KdGhlbWU8LSB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgc2l6ZSA9IDE2LCBhbmdsZSA9IDAsIGhqdXN0ID0gMC41LCB2anVzdCA9IDAsIGZhY2UgPSAicGxhaW4iKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCBzaXplID0gMTYsIGFuZ2xlID0gMCwgaGp1c3QgPSAwLjUsIHZqdXN0ID0gMCwgZmFjZSA9ICJwbGFpbiIpLCAgCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIHNpemUgPSAxOCwgYW5nbGUgPSAwLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAtMSwgZmFjZSA9ICJwbGFpbiIpLAogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCBzaXplID0gMTgsIGFuZ2xlID0gOTAsIGZhY2UgPSAicGxhaW4iKSwKICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBjb2xvdXIgPSAiZ3JleTIwIiksCiAgICAgICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgY29sb3VyID0gImdyZXkyMCIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE4LCBmYWNlID0gImJvbGQiLCBoanVzdCA9IDAuNSwgdmp1c3QgPSAxKSwKICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTgpLCAKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xOCksCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QoY29sb3VyID0gImJsYWNrIiwgZmlsbD1OQSwgc2l6ZT0xKSkKCiNDcmVhdGUgY3VzdG9tIG9yZGVyIHRvIGRpc3BsYXkgeC1heGlzCgpBbGxfY29iYWx0X2RhdGFfY29tYmluZWRfcmVjb3ZlcmllcyRBYmlvdGljX3ZzX2Jpb3RpY19vcmRlcmVkIDwtIGZhY3RvcihBbGxfY29iYWx0X2RhdGFfY29tYmluZWRfcmVjb3ZlcmllcyRBYmlvdGljX3ZzX2Jpb3RpYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJXaWxkIHR5cGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIuKIhnBoeiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3BlbnQgbWVkaXVtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdGVyaWxlIG1lZGl1bSIpKQoKQWJpb3RpY192c19iaW90aWNfd2lyZV9vbmx5X2JveHBsb3RfbG9nMTBfcmVjb3ZlcmllcyA8LSBBbGxfY29iYWx0X2RhdGFfY29tYmluZWRfcmVjb3ZlcmllcyAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoRE1TT190cmVhdG1lbnQgPT0gIk5vIERNU08iKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFNhbXBsZV9wcmVzZXJ2YXRpb24gPT0gIkFjaWRpZmllZCwgZmlsdGVyZWQiKSAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFRpbWUgPT0gMTY4KSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoTWV0YWJvbGl0ZV90cmVhdG1lbnQgPT0gIk5vdGhpbmcgYWRkZWQiKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoV2lyZV90cmVhdG1lbnQgPT0gIldpcmUgaW5jbHVkZWQiKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIVNhbXBsZV9uYW1lID09ICIyMDI0LTAyLTIwXzE2OGhyX1dpcmUrTWVkaWFfMV9BLUYiKSAlPiUgI3N1c3BlY3RlZCBvdXRsaWVyCiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjR3JhcGhpbmcgc2NyaXB0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2dwbG90KGFlcyh4PUFiaW90aWNfdnNfYmlvdGljX29yZGVyZWQsIHk9bG9nMTAoQ29iYWx0X2NvbmNlbnRyYXRpb25fdU1fY29ycmVjdGVkKSkpICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21faml0dGVyKGZpbGwgPSAiZ3JleSIsIGNvbG91ciA9ICJibGFjayIsIHdpZHRoID0gMC4xLCBwY2ggPTIxLCBzdHJva2UgPTEpKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsaW0oMCwgMy41KSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJzKHRpdGxlID0gIiIgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9ICJsb2cxMChDb2JhbHQgY29uY2VudHJhdGlvbiAowrVNKVxuY29ycmVjdGVkIGZvciByZWNvdmVyeSkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggPSAiQWJpb3RpYyBhbmQgYmlvdGljIHRyZWF0bWVudHMiKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUgKyAjdGhpcyBjYWxscyB0aGUgYWVzdGhldGljIHRoZW1lIHZhcmlhYmxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsMSksICJjbSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IC0yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQodmp1c3QgPSAyKSkKCkFiaW90aWNfdnNfYmlvdGljX3dpcmVfb25seV9ib3hwbG90X2xvZzEwX3JlY292ZXJpZXMgI2Fub3RhdGUgdGhpcyBtYW51YWxseSBpbiBhbiBpbWFnZSBlZGl0b3IKZ2dzYXZlKCJGaWdTMUJfQ29iYWx0X0lDUE1TX2RhdGFfYmlvdGljX3RyZWF0bWVudHNfbm9fRE1TT19ib3hwbG90X2xvZzEwX3JlY292ZXJpZXNfYXBwbGllZF8yMDI1MDUxMy5qcGciLCBkcGkgPSAzMDAsIGhlaWdodD02LCB3aWR0aD05LCBkZXZpY2U9anBlZykKZ2dzYXZlKCJGaWdTMUJfQ29iYWx0X0lDUE1TX2RhdGFfYmlvdGljX3RyZWF0bWVudHNfbm9fRE1TT19ib3hwbG90X2xvZzEwX3JlY292ZXJpZXNfYXBwbGllZF8yMDI1MDUxMy4udGlmZiIsIGRwaSA9IDMwMCwgaGVpZ2h0PTYsIHdpZHRoPTksIGRldmljZT10aWZmKQpnZ3NhdmUoIkZpZ1MxQl9Db2JhbHRfSUNQTVNfZGF0YV9iaW90aWNfdHJlYXRtZW50c19ub19ETVNPX2JveHBsb3RfbG9nMTBfcmVjb3Zlcmllc19hcHBsaWVkXzIwMjUwNTEzLnBkZiIsIGRwaSA9IDMwMCwgaGVpZ2h0PTYsIHdpZHRoPTksIGRldmljZT1jYWlyb19wZGYpCmBgYAoKCiMgRmlndXJlIFMyOiBBTk9WQSB0ZXN0IG9uIGFiaW90aWMgY29udHJvbHMgd2l0aCBhbmQgd2l0aG91dCBwaGVuYXppbmUtMS1jYXJib3h5bGljIGFjaWQKCjEuIExvYWQgdGhlIGRhdGEgZnJhbWUgZnJvbSB0aGUgY29tcGlsZWQgZGF0YSBhbmQgcmVtb3ZlIHRoZSBvdXRsaWVyIHZhbHVlIGZyb20gdGhlIHN0ZXJpbGUgbWVkaXVtIHRyZWF0bWVudCB0aGF0IHdhcyBjb250YW1pbmF0ZWQuCmBgYHtyfQpBbGxfY29iYWx0X2RhdGFfY29tYmluZWQgPC0gZnJlYWQoIkFsbF9jb2JhbHRfSUNQTVNfZGF0YV9jbGVhbmVkX2Zvcm1hdHRlZF8yMDI1MDUxMy50eHQiLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSAiYXV0byIpCgojQ3JlYXRlIGN1c3RvbSBvcmRlciBmb3IgeC1heGlzCkFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCRBYmlvdGljX3ZzX2Jpb3RpY19vcmRlcmVkIDwtIGZhY3RvcihBbGxfY29iYWx0X2RhdGFfY29tYmluZWQkQWJpb3RpY192c19iaW90aWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJXaWxkIHR5cGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAi4oiGcGh6IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNwZW50IG1lZGl1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdGVyaWxlIG1lZGl1bSIpKQoKQWxsX2NvYmFsdF9kYXRhX2NvbWJpbmVkJE1ldGFib2xpdGVfdHJlYXRtZW50X29yZGVyZWQgPC0gZmFjdG9yKEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCRNZXRhYm9saXRlX3RyZWF0bWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJOb3RoaW5nIGFkZGVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJQQ0EiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1lT0giKSkKQWJpb3RpY19ub19vdXRsaWVyIDwtIEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCAlPiUKICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihETVNPX3RyZWF0bWVudCA9PSAiTm8gRE1TTyIpICU+JSAjdXNlIHRoaXMgdG8gb25seSBmb2N1cyBvbiBleHBlcmltZW50cyB0aGF0IGRpZCBub3QgcmVjZWl2ZSBETVNPCiAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoU2FtcGxlX3ByZXNlcnZhdGlvbiA9PSAiQWNpZGlmaWVkLCBmaWx0ZXJlZCIpICU+JSAjMjE2IG9ic2VydmF0aW9ucwogICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKFRpbWUgPT0gMTY4ICYgV2lyZV90cmVhdG1lbnQgPT0gIldpcmUgaW5jbHVkZWQiKSAlPiUgI09ubHkgbG9vayBhdCBubyBtZXRhYm9saXRlIHNwaWtlcyArIDE2OCBob3VycwogICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKEFiaW90aWNfdnNfYmlvdGljX29yZGVyZWQgPT0gIlN0ZXJpbGUgbWVkaXVtIikgJT4lCiAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIVNhbXBsZV9uYW1lID09ICIyMDI0LTAyLTIwXzE2OGhyX1dpcmUrTWVkaWFfMV9BLUYiKSAjcmVtb3ZlIG91dGxpZXIKYGBgCgoyLiBHZW5lcmF0ZSB0aGUgbGluZWFyIG1vZGVscyBhbmQgdmVyaWZ5IGFzc3VtcHRpb25zIGZvciB0aGUgQU5PVkEgdXNpbmcgdHlwZSBJSUkgc3VtIG9mIHNxdWFyZXMuCmBgYHtyfQojI0dlbmVyYXRlIG1vZGVsCkFiaW90aWNfbW9kZWxfb3V0bGllcl9yZW1vdmVkIDwtIGxtKENvYmFsdF9jb25jZW50cmF0aW9uX3VNIH4gTWV0YWJvbGl0ZV90cmVhdG1lbnQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gQWJpb3RpY19ub19vdXRsaWVyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJhc3RzID0gbGlzdChNZXRhYm9saXRlX3RyZWF0bWVudCA9IGNvbnRyLnN1bSksIHR5cGUgPTMpCgpBYmlvdGljX21vZGVsX291dGxpZXJfcmVtb3ZlZApwYXIobWZyb3cgPSBjKDIsMikpCnBsb3QoQWJpb3RpY19tb2RlbF9vdXRsaWVyX3JlbW92ZWQpCgojUnVuIEJyZXVzY2ggUGFnYW4gdGVzdCBmb3IgaG9tb3NjZWRhc3RpY2l0eQpicHRlc3QoQWJpb3RpY19tb2RlbF9vdXRsaWVyX3JlbW92ZWQpCgojUnVuIFNoYXBpcm8tV2lsayBub3JtYWxpdHkgdGVzdApzaGFwaXJvLnRlc3QoQWJpb3RpY19tb2RlbF9vdXRsaWVyX3JlbW92ZWQkcmVzaWR1YWxzKQoKI1J1biBEdXJiaW4tV2F0c29uIHRlc3QgZm9yIGF1dG9jb3JyZWxhdGlvbgpkd3Rlc3QoQWJpb3RpY19tb2RlbF9vdXRsaWVyX3JlbW92ZWQpCmBgYAojIyMgSW50ZXJwcmV0YXRpb24KLSBIb21vc2NlZGFzdGljaXR5IG1heSBiZSBhbiBpc3N1ZSwgaXQgbG9va3MgbGlrZSBzYW1wbGVzIGFzc29jaWF0ZWQgd2l0aCBoaWdoZXIgY29iYWx0IGNvbmNlbnRyYXRpb25zIH4gMjQwIMK1TSBoYXZlIGhpZ2hlciB2YXJpYW5jZS4KLSBOb3JtYWwgZGlzdHJpYnV0aW9uIG9mIHJlc2lkdWFscyBsb29rcyBnb29kLgotIEJQIHRlc3QgcmV0dXJucyBhIHAtdmFsdWUgb2YgKjAuMjYxMyogLS0+IHdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBvZiBob21vc2NlZGFzdGljaXR5LgotIFNXIHRlc3QgcmV0dXJucyBhIHAtdmFsdWUgb2YgKjAuMzc1MyogLS0+IHdlIGNhbm5vdCByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyBvZiBub3JtYWxseSBkaXN0cmlidXRlZCByZXNpZHVhbHMuCi0gRFcgdGVzdCByZXR1cm5zIGEgcC12YWx1ZSBvZiAqMC45MTg4KiAtLT4gd2UgY2Fubm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgdGhlcmUgaXMgbm8gYXV0b2NvcnJlbGF0aW9uIGJldHdlZW4gZGF0YSBwb2ludHMuCgoqKkFsbCBhc3N1bXB0aW9ucyBtZXQsIG9rYXkgdG8gcHJvY2VlZCB3aXRoIEFOT1ZBKioKCjMuIFJ1biB0aGUgQU5PVkEgYW5kIHRoZSBUdWtleSBjb21wYXJpc29uLgpgYGB7cn0KQWJpb3RpY190eXBlX0lJSV9BTk9WQV9yZXN1bHRzIDwtIEFub3ZhKEFiaW90aWNfbW9kZWxfb3V0bGllcl9yZW1vdmVkLCB0eXBlID0gMykKQWJpb3RpY190eXBlX0lJSV9BTk9WQV9yZXN1bHRzCmBgYAoKIyMjIEludGVycHJldGF0aW9uCi0gTWV0YWJvbGl0ZSB0cmVhdG1lbnQgZGlkIG5vdCBlbWVyZ2UgYXMgYSBzaWduaWZpY2FudCB2YXJpYWJsZSwgc28gdGhlcmUgaXMgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgYmV0d2VlbiBncm91cHMuCgo0LiBHZW5lcmF0ZSB0aGUgYm94cGxvdC4gVGhlcmUgaXMgbm8gbmVlZCB0byBhbm5vdGF0ZSB0aGUgYm94ZXMgbGF0ZXIgYmVjYXVzZSB0aGVyZSBhcmUgbm8gc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMuCmBgYHtyfQpBYmlvdGljX291dGxpZXJfcmVtb3ZlZF9ib3hwbG90IDwtIEFiaW90aWNfbm9fb3V0bGllciAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZ3Bsb3QoYWVzKHg9TWV0YWJvbGl0ZV90cmVhdG1lbnRfb3JkZXJlZCwgeT1Db2JhbHRfY29uY2VudHJhdGlvbl91TSkpICsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9ib3hwbG90KCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21faml0dGVyKGZpbGwgPSAiZ3JleSIsIGNvbG91ciA9ICJibGFjayIsIHdpZHRoID0gMC4xLCBwY2ggPTIxLCBzdHJva2UgPTEpKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsaW0oMCwgNDAwKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFicyh0aXRsZSA9ICIiICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gIkNvYmFsdCBjb25jZW50cmF0aW9uICjCtU0pIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCA9ICJNZXRhYm9saWMgdHJlYXRtZW50cyBpbiBzdGVyaWxlIG1lZGl1bSIpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsMSksICJjbSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IC0yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQodmp1c3QgPSAyKSkKQWJpb3RpY19vdXRsaWVyX3JlbW92ZWRfYm94cGxvdApnZ3NhdmUoIkZpZ1MyX0NvYmFsdF9JQ1BNU19kYXRhX2FiaW90aWNfdHJlYXRtZW50c19ub19ETVNPX2JveHBsb3QuanBnIiwgZHBpID0gMzAwLCBoZWlnaHQ9Niwgd2lkdGg9NiwgZGV2aWNlPWpwZWcpCmdnc2F2ZSgiRmlnUzJfQ29iYWx0X0lDUE1TX2RhdGFfYWJpb3RpY190cmVhdG1lbnRzX25vX0RNU09fYm94cGxvdC50aWZmIiwgZHBpID0gMzAwLCBoZWlnaHQ9Niwgd2lkdGg9NiwgZGV2aWNlPXRpZmYpCmdnc2F2ZSgiRmlnUzJfQ29iYWx0X0lDUE1TX2RhdGFfYWJpb3RpY190cmVhdG1lbnRzX25vX0RNU09fYm94cGxvdC5wZGYiLCBkcGkgPSAzMDAsIGhlaWdodD02LCB3aWR0aD02LCBkZXZpY2U9Y2Fpcm9fcGRmKQpgYGAKCiMgRmlndXJlIDI6IFBoZW5hemluZSBtZXRhYm9saXRlIGNvbmNlbnRyYXRpb25zIG1lYXN1cmVkIHZpYSBMQy1IUk1TCgoxLiBMb2FkIHRoZSBmb3JtYXR0ZWQgTEMtSFJNUyBkYXRhLgpgYGB7cn0KTENfTVNfZGF0YV9jb21iaW5lZF9sYWJlbGxlZF9sb25nIDwtIGZyZWFkKCJMQ19NU19kYXRhX2NvbWJpbmVkXzIwMjUwNDE5LnR4dCIsIHNlcCA9ICJcdCIsIGhlYWRlciA9ICJhdXRvIikKYGBgCgoyLiBQbG90IHRoZSBzdGFja2VkIGJhciBncmFwaHMgdXNpbmcgdmFyaWFibGVzIHdpdGggYSBjdXN0b20gb3JkZXIuCmBgYHtyfQpiYXJwbG90X3RoZW1lPC0gIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgICAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMubGluZSA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAzMiksCiAgICAgICAgICAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiYmxhY2siLCBzaXplID0gMzIpLAogICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAzNCwgdmp1c3QgPSAtMywgZmFjZSA9ICJib2xkIiksCiAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDM0LCB2anVzdCA9IDYsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIsIHNpemUgPSAzMiwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgICAgICAgICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDMyLCBmYWNlID0gImJvbGQiKSwKICAgICAgICAgICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9NDAsIHZqdXN0ID0gMiwgZmFjZSA9ICJib2xkIiksIAogICAgICAgICAgICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTM0KSwKICAgICAgICAgICAgICAgICBsZWdlbmQua2V5ID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiLCBjb2xvciA9IE5BKSwKICAgICAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA2OCwgZmFjZSA9ICJib2xkIiwgaGp1c3QgPSAwLjUpLAogICAgICAgICAgICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siLCBmaWxsPU5BLCBzaXplPTEpLAogICAgICAgICAgICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDIsIDIsIDIsIDIpLCAiY20iKSkKCkxDX01TX2RhdGFfY29tYmluZWRfbGFiZWxsZWRfbG9uZyRBYmlvdGljX3ZzX2Jpb3RpY19vcmRlcmVkIDwtIGZhY3RvcihMQ19NU19kYXRhX2NvbWJpbmVkX2xhYmVsbGVkX2xvbmckQWJpb3RpY192c19iaW90aWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiV2lsZCB0eXBlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTcGVudCBtZWRpdW0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIuKIhnBoeiIpKQoKTENfTVNfZGF0YV9jb21iaW5lZF9sYWJlbGxlZF9sb25nJE1ldGFib2xpdGVfb3JkZXJlZCA8LSBmYWN0b3IoTENfTVNfZGF0YV9jb21iaW5lZF9sYWJlbGxlZF9sb25nJE1ldGFib2xpdGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiMi1PSFBDQSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUENBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIyLU9IUEhaIikpCgoKUGhlbmF6aW5lX2JhcnBsb3QgPC0gICBMQ19NU19kYXRhX2NvbWJpbmVkX2xhYmVsbGVkX2xvbmcgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoQ29tbWVudCkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKE1lYW5fY29uY2VudHJhdGlvbl91Z19tTCA9IG1lYW4oQ29uY2VudHJhdGlvbl91Z19tTCkpICU+JQogICAgICAgICAgICAgICAgICAgICAgIGdncGxvdChhZXMoeD0gVGltZSwgeSA9IENvbmNlbnRyYXRpb25fdWdfbUwsIGZpbGwgPSBNZXRhYm9saXRlX29yZGVyZWQpKSArCiAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9iYXIoYWVzKGdyb3VwID0gUmVwbGljYXRlKSwgcG9zaXRpb249InN0YWNrIiwgc3RhdD0iaWRlbnRpdHkiKSArCiAgICAgICAgICAgICAgICAgICAgICAgZmFjZXRfbmVzdGVkKFJlcGxpY2F0ZX5XaXJlX3RyZWF0bWVudCArIEFiaW90aWNfdnNfYmlvdGljX29yZGVyZWQpKwogICAgICAgICAgICAgICAgICAgICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCwgMTY4LCBieSA9IDI0KSkgKwogICAgICAgICAgICAgICAgICAgICAgIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiTWV0YWJvbGl0ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoIjItT0hQQ0EiID0gIiNGQTFGMUUiLCAgICMgUmVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUENBIiA9ICIjRUJBNjAyIiwgICAgICAgIyBHb2xkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMi1PSFBIWiIgPSAiIzAyN0FCMCIgICAgIyBCbHVlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKSsKICAgICAgICAgICAgICAgICAgICAgICAjc2NhbGVfZmlsbF9icmV3ZXIobmFtZSA9ICJNZXRhYm9saXRlIiwgcGFsZXR0ZSA9ICJZbE9yUmQiKSsgCiAgICAgICAgICAgICAgICAgICAgICAgeWxpbSgwLDE1KSArCiAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTAsIGhqdXN0PTAuNSksCiAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDI0LCB2anVzdCA9IDApKSsKICAgICAgICAgICAgICAgICAgICAgICBsYWJzKHggPSAiVGltZSBlbGFwc2VkIChob3VycykiICwgeSA9ICJDb25jZW50cmF0aW9uICjCtWcvbUwpIikgKwogICAgICAgICAgICAgICAgICAgICAgIGJhcnBsb3RfdGhlbWUgKyAKICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShsZWdlbmQua2V5LnNpemUgPSB1bml0KDIsICdjbScpKQoKUGhlbmF6aW5lX2JhcnBsb3QKClBoZW5hemluZV9iYXJwbG90X2FuZ2xlZCA8LSBQaGVuYXppbmVfYmFycGxvdCArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHZqdXN0ID0gMC41KSkKCiNTYXZlIGluIGRpZmZlcmVudCBpbWFnZSBmb3JtYXRzCmdnc2F2ZSgiRmlnMl9waGVuYXppbmVfTENNU19kYXRhX3N0YWNrZWRfYmFycGxvdF9mYWNldGVkLmpwZyIsIGRwaSA9IDMwMCwgaGVpZ2h0PTEyLCB3aWR0aD00MCwgZGV2aWNlPWpwZWcpCmdnc2F2ZSgiRmlnMl9waGVuYXppbmVfTENNU19kYXRhX3N0YWNrZWRfYmFycGxvdF9mYWNldGVkLnRpZmYiLCBkcGkgPSAzMDAsIGhlaWdodD0xMiwgd2lkdGg9NDAsIGRldmljZT10aWZmKQpnZ3NhdmUoIkZpZzJfcGhlbmF6aW5lX0xDTVNfZGF0YV9zdGFja2VkX2JhcnBsb3RfZmFjZXRlZC5wZGYiLCBkcGkgPSAzMDAsIGhlaWdodD0xMiwgd2lkdGg9NDAsIGRldmljZT1jYWlyb19wZGYpCmBgYAojIEZpZ3VyZSAzOiBXaWxkIHR5cGUgdnMg4oiGcGh6IG11dGFudCBjZWxsIGdyb3d0aCBpbiBjb3Jyb3Npb24gYXNzYXlzCgoxLiBMb2FkIHRoZSBwbGF0ZSBjb3VudCBkYXRhLgpgYGB7cn0KUGxhdGVfY291bnRzX2NvbWJpbmVkIDwtIGZyZWFkKCJQbGF0ZV9jb3VudHNfY29tYmluZWRfMjAyNTA1MjcudHh0Iiwgc2VwID0gIlx0IiwgaGVhZGVyID0gImF1dG8iKQpgYGAKCjIuIEFkZCBuZXcgdmFyaWFibGVzIHRvIHRoZSBkYXRhIGZyYW1lIHBhcnNpbmcgdGhlIENvbW1lbnQgdmFyaWFibGUgdGhhdCBjb250YWlucyBkZXRhaWxlZCBpbmZvcm10aW9uIG9uIHRoZSBzYW1wbGUKYGBge3J9ClBsYXRlX2NvdW50c19jb21iaW5lZF90cmVhdG1lbnRzX2FkZGVkIDwtIFBsYXRlX2NvdW50c19jb21iaW5lZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI0FkZCB0aW1lIGFzIGEgbnVtZXJpYyB2YWlyYWJsZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoVGltZSA9IGNhc2Vfd2hlbihncmVwbCgiMGhyIiwgQ29tbWVudCkgfiAiMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCIyNGhyIiwgQ29tbWVudCkgfiAiMjQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiNzJociIsIENvbW1lbnQpIH4gIjcyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoIjE2OGhyIiwgQ29tbWVudCkgfiAiMTY4IikpICU+JQogIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoVGltZSA9IGFzLm51bWVyaWMoVGltZSkpICU+JQogICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjQWRkIHdpcmUgdHJlYXRtZW50IGFzIGEgZGVkaWNhdGVkIHZhcmlhYmxlIGFuZCBsZWF2ZSBhcyBjaGFyYWN0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKFdpcmVfdHJlYXRtZW50ID0gY2FzZV93aGVuKGdyZXBsKCJfV2lyZSIsIENvbW1lbnQpIH4gIldpcmUgaW5jbHVkZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoIk5vV2lyZSIsIENvbW1lbnQpIH4gIk5vIHdpcmUiKSkgJT4lCiAgCiAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNBZGQgc3RyYWluIGluZm9ybWF0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZShTdHJhaW4gPSBjYXNlX3doZW4oZ3JlcGwoIisxMCVpbm9jXyIsIENvbW1lbnQpIH4gIldpbGQgdHlwZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JlcGwoIkRNU08iLCBDb21tZW50KSB+ICJXaWxkIHR5cGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyZXBsKCIwJWlub2PiiIZwaHoiLCBDb21tZW50KSB+ICLiiIZwaHoiKSkgJT4lCiAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNBZGQgRE1TTyBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoRE1TT190cmVhdG1lbnQgPSBjYXNlX3doZW4oIWdyZXBsKCJETVNPIiwgQ29tbWVudCkgfiAiTm8gRE1TTyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVwbCgiK0RNU08iLCBDb21tZW50KSB+ICJETVNPIikpIAoKUGxhdGVfY291bnRzX2NvbWJpbmVkX3N1bW1hcnlfc3RhdGlzdGljcyA8LSBQbGF0ZV9jb3VudHNfY29tYmluZWRfdHJlYXRtZW50c19hZGRlZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cF9ieShTdHJhaW4sIFdpcmVfdHJlYXRtZW50LCBETVNPX3RyZWF0bWVudCwgRmxhc2tfbnVtYmVyLCBUaW1lKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoQ0ZVX21MID4wKSAlPiUgI3JlbW92ZSBhbnkgdmFsdWVzIHRoYXQgaGFkIDAgY291bnRzIG9uIHRoZSBwbGF0ZSBmb3IgZ3JhcGhpbmcKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI0NhbGN1bGF0ZSBwbGF0ZSBjb3VudHMgdXNpbmcgdGVjaG5pY2FsIHJlcGxpY2F0ZXMgZm9yIGVhY2ggZmxhc2sgYXQgZWFjaCB0aW1lIHBvaW50CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKFRlY2huaWNhbF9tZWFuX0NGVV9tTCA9IG1lYW4oQ0ZVX21MKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVjaG5pY2FsX3N0ZGV2X0NGVV9tTCA9IHNkKENGVV9tTCkpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5ncm91cCgpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNDYWxjdWxhdGUgcGxhdGUgY291bnRzIHVzaW5nIGF2ZXJhZ2Ugb2YgdGVjaG5pY2FsIHJlcGxpY2F0ZXMgZm9yIGFsbCBmbGFza3MgKGJpb2xvZ2ljYWwgcmVwbGljYXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoU3RyYWluLCBXaXJlX3RyZWF0bWVudCwgRE1TT190cmVhdG1lbnQsIFRpbWUpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKEJpb2xvZ2ljYWxfbWVhbl9DRlVfbUwgPSBtZWFuKFRlY2huaWNhbF9tZWFuX0NGVV9tTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaW9sb2dpY2FsX3N0ZGV2X0NGVV9tTCA9IHNkKFRlY2huaWNhbF9tZWFuX0NGVV9tTCkpCgp3cml0ZS50YWJsZShQbGF0ZV9jb3VudHNfY29tYmluZWRfc3VtbWFyeV9zdGF0aXN0aWNzLCBmaWxlID0gIlBsYXRlX2NvdW50c19jb21iaW5lZF9zdW1tYXJ5X3N0YXRpc3RpY3NfMjAyNTA0MTkudHh0Iiwgc2VwID0gIlx0IiwgCiAgICAgICAgICAgIHJvdy5uYW1lcyA9IEZBTFNFLCBjb2wubmFtZXMgPSBUUlVFKSAKYGBgCgozLiBQbG90IHRoZSBncm93dGggZGF0YSwgc3VtbWFyaXppbmcgdGhlIG1lYW5zIGFuZCBzdGFuZGFyZCBkZXZpYXRpb25zIHByaW9yIHRvIHRoZSBnZ3Bsb3QgY29tbWFuZC4KYGBge3J9CiNBZGp1c3QgdGhlIHByZXNlbnRhdGlvbiBhZXN0aGV0aWNzCnRoZW1lPC0gdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIAogICAgICAgIHNpemUgPSAzMiwgYW5nbGUgPSAwLCBoanVzdCA9IC41LCB2anVzdCA9IC41LCBmYWNlID0gInBsYWluIiksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgCiAgICAgICAgc2l6ZSA9IDMyLCBhbmdsZSA9IDAsIGhqdXN0ID0gMSwgdmp1c3QgPSAwLCBmYWNlID0gInBsYWluIiksICAKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgCiAgICAgICAgc2l6ZSA9IDM0LCBhbmdsZSA9IDAsIGhqdXN0ID0gLjUsIHZqdXN0ID0gMCwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIAogICAgICAgIHNpemUgPSAzNCwgYW5nbGUgPSA5MCwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAzMiwgY29sb3VyID0gImdyZXkyMCIsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIHN0cmlwLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMzIsIGNvbG91ciA9ICJncmV5MjAiKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAzMCwgZmFjZSA9ICJib2xkIiwgaGp1c3QgPSAuNSksCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTMyLCBmYWNlID0gImJvbGQiKSwgCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MzIpLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siLCBmaWxsPU5BLCBzaXplPTEpKQoKI0NyZWF0ZSBjdXN0b20gZGlzcGxheSBvcmRlcnMKUGxhdGVfY291bnRzX2NvbWJpbmVkX3RyZWF0bWVudHNfYWRkZWQkU3RyYWluX29yZGVyZWQgPC0gZmFjdG9yKFBsYXRlX2NvdW50c19jb21iaW5lZF90cmVhdG1lbnRzX2FkZGVkJFN0cmFpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIldpbGQgdHlwZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICLiiIZwaHoiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3BlbnQgbWVkaXVtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlN0ZXJpbGUgbWVkaXVtIikpCgoKR3Jvd3RoX2N1cnZlc19sb2dfc2NhbGUgPC0gUGxhdGVfY291bnRzX2NvbWJpbmVkX3RyZWF0bWVudHNfYWRkZWQgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihETVNPX3RyZWF0bWVudCA9PSAiTm8gRE1TTyIpICU+JSAjdXNlIHRoaXMgdG8gb25seSBmb2N1cyBvbiBleHBlcmltZW50cyB0aGF0IGRpZCBub3QgcmVjZWl2ZSBETVNPCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KFN0cmFpbiwgV2lyZV90cmVhdG1lbnQsIERNU09fdHJlYXRtZW50LCBGbGFza19udW1iZXIsIFRpbWUpICU+JQogIAogICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoQ0ZVX21MID4wKSAlPiUgI3JlbW92ZSBhbnkgdmFsdWVzIHRoYXQgaGFkIDAgY291bnRzIG9uIHRoZSBwbGF0ZSBmb3IgZ3JhcGhpbmcKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICNDYWxjdWxhdGUgcGxhdGUgY291bnRzIHVzaW5nIHRlY2huaWNhbCByZXBsaWNhdGVzIGZvciBlYWNoIGZsYXNrIGF0IGVhY2ggdGltZSBwb2ludAogICAgICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGUoVGVjaG5pY2FsX21lYW5fQ0ZVX21MID0gbWVhbihDRlVfbUwpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGVjaG5pY2FsX3N0ZGV2X0NGVV9tTCA9IHNkKENGVV9tTCkpICU+JQogICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5ncm91cCgpICU+JQogICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICNDYWxjdWxhdGUgcGxhdGUgY291bnRzIHVzaW5nIGF2ZXJhZ2Ugb2YgdGVjaG5pY2FsIHJlcGxpY2F0ZXMgZm9yIGFsbCBmbGFza3MgKGJpb2xvZ2ljYWwgcmVwbGljYXRlcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfYnkoU3RyYWluLCBXaXJlX3RyZWF0bWVudCwgRE1TT190cmVhdG1lbnQsIFRpbWUpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRlKEJpb2xvZ2ljYWxfbWVhbl9DRlVfbUwgPSBtZWFuKFRlY2huaWNhbF9tZWFuX0NGVV9tTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaW9sb2dpY2FsX3N0ZGV2X0NGVV9tTCA9IHNkKFRlY2huaWNhbF9tZWFuX0NGVV9tTCkpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgI3Bsb3R0aW5nIHNjcmlwdAogICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdChhZXMoeD1UaW1lLCB5ID0gbG9nMTAoQmlvbG9naWNhbF9tZWFuX0NGVV9tTCksIGNvbG91ciA9IFN0cmFpbl9vcmRlcmVkKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX3BvaW50KHNpemUgPSA2KSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSBsb2cxMChCaW9sb2dpY2FsX21lYW5fQ0ZVX21MIC0gQmlvbG9naWNhbF9zdGRldl9DRlVfbUwpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bWF4ID0gbG9nMTAoQmlvbG9naWNhbF9tZWFuX0NGVV9tTCArIEJpb2xvZ2ljYWxfc3RkZXZfQ0ZVX21MKSkpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKGFlcyhncm91cCA9IEZsYXNrX251bWJlciwgY29sb3IgPSBTdHJhaW5fb3JkZXJlZCkpKwogICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDE2OCwgYnkgPSAyNCkpKwogICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNldF9ncmlkKH4gV2lyZV90cmVhdG1lbnQpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgeWxhYigiTG9nMTBcbihDRlUvbUwpIikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gbGFiZWxfbWF0aCgpLCBsaW1pdHMgPSBjKDUsIDEwKSkrCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIoIlRpbWUgZWxhcHNlZCAoaG91cnMpIikgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWUgPSAiU3RyYWluIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gd2VzX3BhbGV0dGUoIkRhcmplZWxpbmcxIiwgbiA9IDQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIldpbGQgdHlwZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cHJlc3Npb24oaXRhbGljKCLiiIZwaHoiKSkpKSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlbWUgKwogICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IC0yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gMikpCiAgICAgICAgICAKR3Jvd3RoX2N1cnZlc19sb2dfc2NhbGUKCkdyb3d0aF9jdXJ2ZXNfbG9nX3NjYWxlX25vX2xlZ2VuZF9hbmdsZWQgPC0gR3Jvd3RoX2N1cnZlc19sb2dfc2NhbGUgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1KSkKCmdnc2F2ZSgiRmlnM19wbGF0ZV9jb3VudF9kYXRhX1dUX3Boel9tdXRhbnRfc2NhdHRlcnBsb3RfbG9nMTAuanBnIiwgZHBpID0gMzAwLCBoZWlnaHQ9OCwgd2lkdGg9MjAsIGRldmljZT1qcGVnKQpnZ3NhdmUoIkZpZzNfcGxhdGVfY291bnRfZGF0YV9XVF9waHpfbXV0YW50X3NjYXR0ZXJwbG90X2xvZzEwLnRpZmYiLCBkcGkgPSAzMDAsIGhlaWdodD04LCB3aWR0aD0yMCwgZGV2aWNlPXRpZmYpCmdnc2F2ZSgiRmlnM19wbGF0ZV9jb3VudF9kYXRhX1dUX3Boel9tdXRhbnRfc2NhdHRlcnBsb3RfbG9nMTAucGRmIiwgZHBpID0gMzAwLCBoZWlnaHQ9OCwgd2lkdGg9MjAsIGRldmljZT1jYWlyb19wZGYpCmBgYAojIEZpZ3VyZSBTNTogQ29iYWx0IGNvbmNlbnRyYXRpb25zIGZvciB3aWxkIHR5cGUgY2VsbHMgdGhhdCB3ZXJlIGFjaWRpZmllZCB0aGVuIGZpbHRlcmVkLCBvciBmaWx0ZXJlZCB0aGVuIGFjaWRpZmllZAoKMS4gVXNlIHRoZSBjb2RlIGJlbG93IHRvIGxvYWQgaW4gc291cmNlIGRhdGEuCmBgYHtyfQpBbGxfY29iYWx0X2RhdGFfY29tYmluZWQgPC0gZnJlYWQoIkFsbF9jb2JhbHRfSUNQTVNfZGF0YV9jbGVhbmVkX2Zvcm1hdHRlZF8yMDI1MDUxMy50eHQiLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSAiYXV0byIpCmBgYAoKMi4gVXNlIHRoaXMgY29kZSB0byBjcmVhdGUgYSBzaW1pbGFyIGZpZ3VyZSB0byBGaWd1cmUgMSBjb21wYXJpbmcgd2lsZCB0eXBlIGFuZCBzdGVyaWxlIG1lZGl1bSB0cmVhdG1lbnRzIHRoYXQgZGlkIG5vdCByZWNlaXZlIERNU08gYW5kIHdlcmUgc3ViamVjdCB0byBkaWZmZXJlbnQgc2FtcGxlIHByZXNlcnZhdGlvbiBtZXRob2RzLgpgYGB7cn0KI0FkanVzdCB0aGUgcHJlc2VudGF0aW9uIGFlc3RoZXRpY3MKdGhlbWU8LSB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLCBheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgCiAgICAgICAgc2l6ZSA9IDMyLCBhbmdsZSA9IDAsIGhqdXN0ID0gLjUsIHZqdXN0ID0gLjUsIGZhY2UgPSAicGxhaW4iKSwKICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCAKICAgICAgICBzaXplID0gMzIsIGFuZ2xlID0gMCwgaGp1c3QgPSAxLCB2anVzdCA9IDAsIGZhY2UgPSAicGxhaW4iKSwgIAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJncmV5MjAiLCAKICAgICAgICBzaXplID0gMzQsIGFuZ2xlID0gMCwgaGp1c3QgPSAuNSwgdmp1c3QgPSAwLCBmYWNlID0gImJvbGQiKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgCiAgICAgICAgc2l6ZSA9IDM0LCBhbmdsZSA9IDkwLCBmYWNlID0gImJvbGQiKSwKICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDMyLCBjb2xvdXIgPSAiZ3JleTIwIiwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgc3RyaXAudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAzMiwgY29sb3VyID0gImdyZXkyMCIpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDMwLCBmYWNlID0gImJvbGQiLCBoanVzdCA9IC41KSwKICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MzIsIGZhY2UgPSAiYm9sZCIpLCAKICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT0zMiksCiAgICAgICAgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGNvbG91ciA9ICJibGFjayIsIGZpbGw9TkEsIHNpemU9MSkpCgoKI0dyYXBoaW5nIHNjcmlwdCB3aXRoIGFkZGl0aW9uYWwgZGF0YSBtYW5pcHVsYXRpb24KQWNpZGlmeV9maWx0ZXJfc2NhdHRlcnBsb3QgPC0gIEFsbF9jb2JhbHRfZGF0YV9jb21iaW5lZCAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihXaXJlX3RyZWF0bWVudCA9PSAiV2lyZSBpbmNsdWRlZCIpICU+JSAjdXNlIHRoaXMgdG8gb25seSBmb2N1cyBvbiBleHBlcmltZW50cyB0aGF0IGRpZCBub3QgcmVjZWl2ZSBETVNPCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoQWJpb3RpY192c19iaW90aWMgPT0gIldpbGQgdHlwZSIgfCBBYmlvdGljX3ZzX2Jpb3RpYyA9PSAiU3RlcmlsZSBtZWRpdW0iKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihNZXRhYm9saXRlX3RyZWF0bWVudCA9PSAiTm90aGluZyBhZGRlZCIpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKERNU09fdHJlYXRtZW50ID09ICJObyBETVNPIikgJT4lICM5NiBvYnNlcnZhdGlvbnMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KEFiaW90aWNfdnNfYmlvdGljLCBXaXJlX3RyZWF0bWVudCwgRE1TT190cmVhdG1lbnQsIE1ldGFib2xpdGVfdHJlYXRtZW50LCBUaW1lLCBTYW1wbGVfcHJlc2VydmF0aW9uKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wgPSBtZWFuKENvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1lZGlhbl9jb2JhbHRfY29uY2VudHJhdGlvbl91Z19MID0gbWVkaWFuKENvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0ZGV2X2NvYmFsdF9jb25jZW50cmF0aW9uX3VnX0wgPSBzZChDb2JhbHRfY29uY2VudHJhdGlvbl91Z19MKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNaW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdWdfTCA9IG1pbihDb2JhbHRfY29uY2VudHJhdGlvbl91Z19MKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXhfY29iYWx0X2NvbmNlbnRyYXRpb25fdWdfTCA9IG1heChDb2JhbHRfY29uY2VudHJhdGlvbl91Z19MKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNZWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VNID0gbWVhbihDb2JhbHRfY29uY2VudHJhdGlvbl91TSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWVkaWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VNID0gbWVkaWFuKENvYmFsdF9jb25jZW50cmF0aW9uX3VNKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGRldl9jb2JhbHRfY29uY2VudHJhdGlvbl91TSA9IHNkKENvYmFsdF9jb25jZW50cmF0aW9uX3VNKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNaW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdU0gPSBtaW4oQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1heF9jb2JhbHRfY29uY2VudHJhdGlvbl91TSA9IG1heChDb2JhbHRfY29uY2VudHJhdGlvbl91TSkpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxvY2F0ZShNZWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VnX0w6TWF4X2NvYmFsdF9jb25jZW50cmF0aW9uX3VNLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFmdGVyID0gQ29iYWx0X2NvbmNlbnRyYXRpb25fdU0pICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcighQm90dGxlX251bWJlciA9PSAiMSIpICU+JSAjcmVtb3ZlIG91dGxpZXIgc3RlcmlsZSBjb250cm9sCiAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNwbG90dGluZyBzY3JpcHQKICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdncGxvdChhZXMoeD1UaW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IE1lYW5fY29iYWx0X2NvbmNlbnRyYXRpb25fdU0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBBYmlvdGljX3ZzX2Jpb3RpYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fcG9pbnQoc2l6ZSA9IDYpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluID0gTWVhbl9jb2JhbHRfY29uY2VudHJhdGlvbl91TSAtIFN0ZGV2X2NvYmFsdF9jb25jZW50cmF0aW9uX3VNLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHltYXggPSBNZWFuX2NvYmFsdF9jb25jZW50cmF0aW9uX3VNICsgU3RkZXZfY29iYWx0X2NvbmNlbnRyYXRpb25fdU0pKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9saW5lKGFlcyhncm91cCA9IEJvdHRsZV9udW1iZXIsIGNvbG9yID0gQWJpb3RpY192c19iaW90aWMpKSsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDE2OCwgYnkgPSAyNCkpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNldF9ncmlkKH4gU2FtcGxlX3ByZXNlcnZhdGlvbikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlsYWIoIkNvYmFsdCBjb25jZW50cmF0aW9uICjCtU0pIikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhsYWIoIlRpbWUgZWxhcHNlZCAoaG91cnMpIikgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZSA9ICJBYmlvdGljIHZzIGJpb3RpYyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSB3ZXNfcGFsZXR0ZSgiQ2F2YWxjYW50aTEiLCBuID0gMikpKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICNzY2FsZV9zaGFwZV9kaXNjcmV0ZShuYW1lID0gIkFiaW90aWMgdnMgYmlvdGljIikgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZW1lICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHZqdXN0ID0gLTIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUpKQoKQWNpZGlmeV9maWx0ZXJfc2NhdHRlcnBsb3QKCiNTYXZlIHRoZSBpbWFnZXMgaW4gZGlmZmVyZW50IGZvcm1hdHMKZ2dzYXZlKCJGaWdTNV9jb2JhbHRfSUNQTVNfZGF0YV9zYW1wbGVfcHJlc2VydmF0aW9uX3NjYXR0ZXJwbG90LmpwZyIsIGRwaSA9IDMwMCwgaGVpZ2h0PTgsIHdpZHRoPTIwLCBkZXZpY2U9anBlZykKZ2dzYXZlKCJGaWdTNV9jb2JhbHRfSUNQTVNfZGF0YV9zYW1wbGVfcHJlc2VydmF0aW9uX3NjYXR0ZXJwbG90LnRpZmYiLCBkcGkgPSAzMDAsIGhlaWdodD04LCB3aWR0aD0yMCwgZGV2aWNlPXRpZmYpCmdnc2F2ZSgiRmlnUzVfY29iYWx0X0lDUE1TX2RhdGFfc2FtcGxlX3ByZXNlcnZhdGlvbl9zY2F0dGVycGxvdC5wZGYiLCBkcGkgPSAzMDAsIGhlaWdodD04LCB3aWR0aD0yMCwgZGV2aWNlPWNhaXJvX3BkZikKYGBgCgojIEZpZ3VyZSBTNi4gRG9zZSByZXNwb25zZSBjdXJ2ZXMgZm9yIHdpbGQgdHlwZSBjZWxsIGdyb3d0aCByYXRlIGFzIGEgZnVuY3Rpb24gb2YgY29iYWx0IGNvbmNlbnRyYXRpb24KCjEuIExvYWQgdGhlIHN1bW1hcmllcyBnZW5lcmF0ZWQgd2l0aCB0aGUgJ2dyb3d0aGN1cnZlcicgcGFja2FnZSB0aGF0IGFyZSB0aGUgc291cmNlIGRhdGEgZm9yIHRoZSBkb3NlIHJlc3BvbnNlIGN1cnZlLgpgYGB7cn0KUF9jaGxvcl9hdXJfZ3Jvd3RoX3N1bW1hcnlfdmFyaWFibGVzX2FkZGVkIDwtIGZyZWFkKCJQc2V1ZG9tb25hc19jaGxvcm9yYXBoaXNfYXVyZWZvY2llbnNfZ3Jvd3RoX2N1cnZlX3N1bW1hcmllcy50eHQiLCBzZXAgPSAiXHQiLCBoZWFkZXIgPSAiYXV0byIpCmBgYAoKMi4gVXNlIHRoZSBjb21tYW5kcyBpbiB0aGUgJ2RyYycgcGFja2FnZSB0byBmaXQgYSA1IHBhcmFtZXRlciBsb2dpc3RpYyByZWdyZXNzaW9uIHRvIGNyZWF0ZSB0aGUgZG9zZSByZXNwb25zZSBjdXJ2ZS4gVXNlIHRoZSBzdW1tYXJ5IGNvbW1hbmRzIHRvIGdldCBxdWljayBpbmZvcm1hdGlvbiBvbiB0aGUgSUMvRUM1MCB2YWx1ZXMgZm9yIGNvYmFsdCBjb25jZW50cmF0aW9uLgpgYGB7cn0KUF9jaGxvcl9hdXJfZ3Jvd3RoX3JhdGVfNV9wYXJhbV9tb2RlbDwtIGRybShyIH4gQ29iYWx0X2NvbmNlbnRyYXRpb25fdU1fbnVtZXJpYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IFBfY2hsb3JfYXVyX2dyb3d0aF9zdW1tYXJ5X3ZhcmlhYmxlc19hZGRlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmN0ID0gTEwuNSgpKQoKc3VtbWFyeShQX2NobG9yX2F1cl9ncm93dGhfcmF0ZV81X3BhcmFtX21vZGVsKQpQX2NobG9yX2F1cl9ncm93dGhfcmF0ZV9zdW1tYXJ5X2Rvc2VfZGF0YSA8LSBFRChQX2NobG9yX2F1cl9ncm93dGhfcmF0ZV81X3BhcmFtX21vZGVsLCBjKDUsIDEwLCA1MCksIGludGVydmFsID0gImRlbHRhIikKYGBgCgozLiBQbG90IHRoZSBkb3NlIHJlc3BvbnNlIGN1cnZlIHVzaW5nIGJhc2UgUiAobW9zdCBjb21wYXRpYmxlIHdpdGggdGhlIGRyYyBwYWNrYWdlKS4KYGBge3J9ClBfY2hsb3JfYXVyX2dyb3d0aF9yYXRlX2Rvc2VfcmVzcG9uc2U8LSBwbG90KFBfY2hsb3JfYXVyX2dyb3d0aF9yYXRlXzVfcGFyYW1fbW9kZWwsIGJyb2tlbiA9IEZBTFNFLCB0eXBlID0gImFsbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bGFiID0gIkNvKDIrKSBjb25jZW50cmF0aW9uICjCtU0pIiwgeGxpbSA9IGMoMCwgMTAwMCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5bGFiID0gIkdyb3d0aCByYXRlIChoci0xKSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFpbiA9ICJQc2V1ZG9tb25hcyBjaGxvcm9yYXBoaXMgYXVyZW9mYWNpZW5zIGdyb3d0aCBjdXJ2ZSBpbiByZXNwb25zZSB0byBDbygyKykiKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCnZpZXcoUF9jaGxvcl9hdXJfZ3Jvd3RoX3JhdGVfZG9zZV9yZXNwb25zZSkKCiNTYXZlIGFzIHBkZiB1c2luZyBiYXNlIFIKcGRmKGZpbGUgPSAnRmlnUzZfUHNldWRvbW9uYXNfY2hsb3JvcmFwaGlzX2F1cmVvZmFjaWVuc19ncm93dGhfcmF0ZV9jb2JhbHRfZG9zZV9yZXNwb25zZV9jdXJ2ZS5wZGYnKQpwbG90KFBfY2hsb3JfYXVyX2dyb3d0aF9yYXRlXzVfcGFyYW1fbW9kZWwsIGJyb2tlbiA9IEZBTFNFLCB0eXBlID0gImFsbCIsCnhsYWIgPSAiQ28oMispIGNvbmNlbnRyYXRpb24gKMK1TSkiLCB4bGltID0gYygwLCAxMDAwKSwKeWxhYiA9ICJHcm93dGggcmF0ZSAoaHItMSkiLCAKbWFpbiA9ICJQc2V1ZG9tb25hcyBjaGxvcm9yYXBoaXMgYXVyZW9mYWNpZW5zIFxuZ3Jvd3RoIGN1cnZlIGluIHJlc3BvbnNlIHRvIENvKDIrKSIpCmRldi5vZmYoKQpgYGAKCiNGaWd1cmUgUzE0OiBBTk9WQSB0ZXN0IG9uIGxpdmUgY2VsbHMgd2l0aCBhbmQgd2l0aG91dCBETVNPCgoxLiBMb2FkIHRoZSBzb3VyY2UgZGF0YSBhbmQgdHJpbSBpdCB0byB0aGUgZGVzaXJlZCBzYW1wbGVzIHRvIGNhcnJ5IG91dCB0aGUgY29tcGFyaXNvbiBmb3IgdGhlIGVmZmVjdCBvZiBETVNPLgpgYGB7cn0KQWxsX2NvYmFsdF9kYXRhX2NvbWJpbmVkIDwtIGZyZWFkKCJBbGxfY29iYWx0X0lDUE1TX2RhdGFfY2xlYW5lZF9mb3JtYXR0ZWRfMjAyNTA1MTMudHh0Iiwgc2VwID0gIlx0IiwgaGVhZGVyID0gImF1dG8iKQoKI1N1YmV0IERNU08gZGF0YQpETVNPX2NvbXBhcmlzb25fZGF0YSA8LSBBbGxfY29iYWx0X2RhdGFfY29tYmluZWQgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihXaXJlX3RyZWF0bWVudCA9PSAiV2lyZSBpbmNsdWRlZCIpICU+JQogICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoU2FtcGxlX3ByZXNlcnZhdGlvbiA9PSAiQWNpZGlmaWVkLCBmaWx0ZXJlZCIpICU+JQogICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoVGltZSA9PSAxNjgpICU+JQogICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoQWJpb3RpY192c19iaW90aWMgPT0gIldpbGQgdHlwZSIpCmBgYAoKMi4gVXNlIHRoZSBzdWJzZXQgZGF0YSB0byBnZW5lcmF0ZSBhIGxpbmVhciBtb2RlbCB0aGF0IGZvciBhbiBBTk9WQSBjb21wYXJpc29uLiBVc2UgdGhpcyBjb2RlIHRvIHZlcmlmeSB0aGUgYXNzdW1wdGlvbnMgb2YgbGluZWFyIG1vZGVsIGZpdC4KYGBge3J9CkRNU09fY29tcGFyaXNvbl9tb2RlbCA8LSBsbShDb2JhbHRfY29uY2VudHJhdGlvbl91TSB+IERNU09fdHJlYXRtZW50LCBkYXRhID0gRE1TT19jb21wYXJpc29uX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cmFzdHMgPSBsaXN0KERNU09fdHJlYXRtZW50ID0gY29udHIuc3VtKSwgdHlwZSA9MykgI25lZWQgdG8gZG8gdGhpcyBmb3IgdW5hYmFsYW5jZSBzYW1wbGUgc2l6ZQpETVNPX2NvbXBhcmlzb25fbW9kZWwKcGFyKG1mcm93ID0gYygyLDIpKQpwbG90KERNU09fY29tcGFyaXNvbl9tb2RlbCkKYGBgCgojIyMgSW50ZXJwcmV0YXRpb24KLSBMb29rcyBsaWtlIHdlIG1heSBoYXZlIGlzc3VlcyB3aXRoIGVxdWFsIHZhcmlhbmNlIGluIHRoZSBhYnNlbmNlIG9mIERNU08uCi0gTm9ybWFsaXR5IGxvb2tzIHByZXR0eSBnb29kIGV4Y3BldCBmb3IgdGhlIDV0aCBhbmQgN3RoIGRhdGEgcG9pbnRzLgoKMy4gUnVuIGZvcm1hbCB0ZXN0cyB0byB2ZXJpZnkgdGhlIGFzc3VtcHRpb25zIG9mIGxpbmVhciBtb2RlbHMuCmBgYHtyfQojUnVuIEJyZXVzY2ggUGFnYW4gdGVzdCBmb3IgaG9tb3NjZWRhc3RpY2l0eQpicHRlc3QoRE1TT19jb21wYXJpc29uX21vZGVsKQoKI1J1biBTaGFwaXItV2lsayBub3JtYWxpdHkgdGVzdApzaGFwaXJvLnRlc3QoRE1TT19jb21wYXJpc29uX21vZGVsJHJlc2lkdWFscykKCiNSdW4gRHVyYmluLVdhdHNvbiB0ZXN0IGZvciBhdXRvY29ycmVsYXRpb24KZHd0ZXN0KERNU09fY29tcGFyaXNvbl9tb2RlbCkKYGBgCgojIyMgSW50ZXJwcmV0YXRpb24KCnN0dWRlbnRpemVkIEJyZXVzY2gtUGFnYW4gdGVzdAoKZGF0YTogIERNU09fY29tcGFyaXNvbl9tb2RlbApCUCA9IDYuNTQ5NywgZGYgPSAzLCBwLXZhbHVlID0gMC4wODU1NyAqcCA+IDAuMDUqIG1lYW5pbmcgd2UgY2Fubm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIG9mIGhvbW9zY2VkYXN0aWNpdHksIHRoaXMgaXMgZ29vZCAoanVzdCBiYXJlbHkpCgoKU2hhcGlyby1XaWxrIG5vcm1hbGl0eSB0ZXN0CgpkYXRhOiAgRE1TT19jb21wYXJpc29uX21vZGVsJHJlc2lkdWFscwpXID0gMC43MjIwNCwgcC12YWx1ZSA9IDAuNzU2OSAqcCA+MC4wNSosIG1lYW5pbmcgd2UgY2Fubm90IHJlamVjdCB0aGUgbnVsbCBoeXBvdGhlc2lzIHRoYXQgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLgoKCkR1cmJpbi1XYXRzb24gdGVzdAoKZGF0YTogIERNU09fY29tcGFyaXNvbl9tb2RlbApEVyA9IDEuOTc4MywgcC12YWx1ZSA9IDAuMjE0MQoKQWx0ZXJuYXRpdmUgaHlwb3RoZXNpczogdHJ1ZSBhdXRvY29ycmVsYXRpb24gaXMgZ3JlYXRlciB0aGFuIDAgKnZhbHVlIGlzIGNsb3NlIHRvIDIsIG5vIHNpZ25pZmljYW50IGF1dG9jb3JyZWxhdGlvbiosICpwID4gMC4wNSogc28gd2UgY2FuJ3QgcmVqZWN0IG51bGwgaHlwb3RoZXNpcyBvZiBubyBhdXRvY29ycmVsYXRpb24KCjMuIFJ1biB0aGUgQU5PVkEgYW5kIHRoZSBUdWtleSBjb21wYXJpc29uLgpgYGB7cn0KRE1TT190eXBlX0lJSV9BTk9WQV9yZXN1bHRzIDwtIEFub3ZhKERNU09fY29tcGFyaXNvbl9tb2RlbCwgdHlwZSA9IDMpCkRNU09fdHlwZV9JSUlfQU5PVkFfcmVzdWx0cwpgYGAKCiMjIyBJbnRlcnByZXRhdGlvbgotIERNU08gdHJlYXRtZW50IGhhZCBhIHNpZ25pZmljYW50IGVmZmVjdCBvbiBjb2JhbHQgY29uY2VudHJhdGlvbiBhdCAxNjggaG91cnMgZm9yIHdpbGQgdHlwZSBjZWxsIGV4cGVyaW1lbnRzLgoKNC4gQ3JlYXRlIGEgYm94cGxvdCB0byBpbGx1c3RyYXRlIHRoaXMgcmVzdWx0LiBUaGVyZSBpcyBubyBuZWVkIHRvIGFubm90YXRlIGJlY2F1c2UgdGhlcmUgYXJlIG9ubHkgdHdvIGJveGVzIGFuZCB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGUgd2FzIHNpZ25pZmljYW50LiAKYGBge3J9CnRoZW1lPC0gdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIAogICAgICAgIHNpemUgPSAzMiwgYW5nbGUgPSAwLCBoanVzdCA9IC41LCB2anVzdCA9IC41LCBmYWNlID0gInBsYWluIiksCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgCiAgICAgICAgc2l6ZSA9IDMyLCBhbmdsZSA9IDAsIGhqdXN0ID0gMSwgdmp1c3QgPSAwLCBmYWNlID0gInBsYWluIiksICAKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiZ3JleTIwIiwgCiAgICAgICAgc2l6ZSA9IDM0LCBhbmdsZSA9IDAsIGhqdXN0ID0gLjUsIHZqdXN0ID0gMCwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImdyZXkyMCIsIAogICAgICAgIHNpemUgPSAzNCwgYW5nbGUgPSA5MCwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAzMiwgY29sb3VyID0gImdyZXkyMCIsIGZhY2UgPSAiYm9sZCIpLAogICAgICAgIHN0cmlwLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMzIsIGNvbG91ciA9ICJncmV5MjAiKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAzMCwgZmFjZSA9ICJib2xkIiwgaGp1c3QgPSAuNSksCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTMyLCBmYWNlID0gImJvbGQiKSwgCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MzIpLAogICAgICAgIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChjb2xvdXIgPSAiYmxhY2siLCBmaWxsPU5BLCBzaXplPTEpKQoKRE1TT19ib3hwbG90IDwtIERNU09fY29tcGFyaXNvbl9kYXRhICU+JQogICAgICAgICAgICAgICAgZ2dwbG90KGFlcyh4PURNU09fdHJlYXRtZW50LCB5PUNvYmFsdF9jb25jZW50cmF0aW9uX3VNKSkgKyAKICAgICAgICAgICAgICAgIGdlb21fYm94cGxvdCgpICsKICAgICAgICAgICAgICAgIGdlb21faml0dGVyKGZpbGwgPSAiZ3JleSIsIGNvbG91ciA9ICJibGFjayIsIHdpZHRoID0gMC4xLCBwY2ggPTIxLCBzdHJva2UgPTEpKwogICAgICAgICAgICAgICAgeWxpbSgwLCAzMDAwKSArCiAgICAgICAgICAgICAgICBsYWJzKHRpdGxlID0gIiIgLAogICAgICAgICAgICAgICAgeSA9ICJDb2JhbHRcbmNvbmNlbnRyYXRpb24gKMK1TSkiLCAKICAgICAgICAgICAgICAgIHggPSAiRE1TTyB0cmVhdG1lbnQiKSArCiAgICAgICAgICAgICAgICB0aGVtZSArCiAgICAgICAgICAgICAgICB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksCiAgICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQodmp1c3QgPSAtMiksCiAgICAgICAgICAgICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQodmp1c3QgPSAyKSwKICAgICAgICAgICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCkpCgpETVNPX2JveHBsb3QKCiNTYXZlIGRpZmZlcmVudCBpbWFnZSBmb3JtYXRzCmdnc2F2ZSgiRmlnUzE0X2NvYmFsdF9JQ1BNU19kYXRhX0RNU08uanBnIiwgZHBpID0gMzAwLCBoZWlnaHQ9OCwgd2lkdGg9MTAsIGRldmljZT1qcGVnKQpnZ3NhdmUoIkZpZ1MxNF9jb2JhbHRfSUNQTVNfZGF0YV9ETVNPLnRpZmYiLCBkcGkgPSAzMDAsIGhlaWdodD04LCB3aWR0aD0xMCwgZGV2aWNlPXRpZmYpCmdnc2F2ZSgiRmlnUzE0X2NvYmFsdF9JQ1BNU19kYXRhX0RNU08ucGRmIiwgZHBpID0gMzAwLCBoZWlnaHQ9OCwgd2lkdGg9MTAsIGRldmljZT1jYWlyb19wZGYpCmBgYAojQmlvaW5mb3JtYXRpY3MgYW5hbHlzZXMgb2YgZ2Vub21lIGFubm90YXRpb25zIGdlbmVyYXRlZCB1c2luZyBEUkFNCgojIyBSdW4gRFJBTSBmb3IgYW5ub3RhdGlvbnMgYW5kIGRpc3RpbGxhdGlvbgoKMS4gQWN0aXZhdGUgdGhlIGNvbmRhIGVudmlyb25tZW50IGNvbnRhaW5pbmcgRFJBTSBhbmQgcnVuIHRoZSBhbm5vdGF0ZSBjb21tYW5kLiBSZXBsYWNlIHRoZSBkaXJlY3RvcnkgYW5kIGZhc3RhIGZpbGUgd2l0aCB0aGUgZ2Vub21lIGZpbGUgZm9yIFBzZXVkb21vbmFzIGNobG9yb3JhcGhpcyBzdWJzcGVjaWVzIGF1cmVmb2FjaWVucyAob3IgYW55IGdlbm9tZSBvciBnZW5vZW1zIG9mIHlvdXIgY2hvaWNlKQpgYGB7YmFzaH0KRFJBTS5weSBhbm5vdGF0ZSAtaSAnUHNldWRvbW9uYXNfZ2Vub21lX2FuYWx5c2VzLyouZmFzdGEnIC0tdXNlX3VuaXJlZiAtbyBQc2V1ZG9tb25hc19hbm5vdGF0aW9uX3dpdGhfdW5pcmVmIC0tdGhyZWFkcyA4CmBgYAoKMi4gT25jZSB0aGUgYW5ub3RhdGlvbiBpcyBjb21wbGV0ZSwgdXNlIHRoZSBkaXN0aWxsYXRpb24gY29tbWFuZC4gTWFrZSBzdXJlIHRvIHVzZSB0aGUgc2FtZSBvdXRwdXQgZGlyZWN0b3J5IGZyb20gdGhlIGFubm90YXRlIHN0ZXAuCmBgYHtiYXNofQpEUkFNLnB5IGRpc3RpbGwgLWkgUHNldWRvbW9uYXNfYW5ub3RhdGlvbl93aXRoX3VuaXJlZi9hbm5vdGF0aW9ucy50c3YgLW8gUHNldWRvbW9uYXNfZ2Vub21lX3N1bW1hcmllcyAtLXRybmFfcGF0aCBQc2V1ZG9tb25hc19hbm5vdGF0aW9uX3dpdGhfdW5pcmVmL3RybmFzLnRzdiAtLXJybmFfcGF0aCBQc2V1ZG9tb25hc19hbm5vdGF0aW9uX3dpdGhfdW5pcmVmL3JybmFzLnRzdgpgYGAKCiMjIE1hbnVhbGx5IHNlYXJjaCBmb3IgY29iYWx0IGdlbmVzIGluIHRoZSBhbm5vdGF0aW9uIG91dHB1dCBieSBEUkFNCgoxLiBMb2FkIGluIHRoZSB0YWItZGVsaW1pdGVkIGZpbGUgY29udGFpbmluZyB0aGUgYW5ub3RhdGlvbiBkYXRhLgpgYGB7cn0KUHNldWRvbW9uYXNfY2hsb3JvcmFwaGlzX2F1cmVvZmFjaWVuc19hbm5vdGF0aW9ucyA8LSBmcmVhZCgiUHNldWRvbW9uYXNfY2hsb3JvcmFwaGlzX2F1cmVvZmFjaWVuc19EUkFNX2Fubm90YXRpb25zLnRzdiIsIHNlcCA9ICJcdCIsIGhlYWRlciA9ICJhdXRvIikKYGBgCgoyLiBNYW51YWxseSBzZWFyY2ggdGhlIGFubm90YXRpb24gZmlsZSB1c2luZyBkaWZmZXJlbnQgc3RyaW5ncyBvZiB0ZXN0IGZvciBmdW5jdGlvbnMgcmVsZXZhbnQgdG8gY29iYWx0IGFuZCBtaWNyb2JpYWxseS1pbmR1Y2VkIGNvcnJvc2lvbi4KYGBge3J9CmNvcnJvc2lvbl9wYXRod2F5cyA8LSBQc2V1ZG9tb25hc19jaGxvcm9yYXBoaXNfYXVyZW9mYWNpZW5zX2Fubm90YXRpb25zICU+JQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgI1NpbXBsZSB0ZXh0IHNlYXJjaCBmb3IgImNvYmFsdCIKICAgICAgICAgICAgICAgICAgIGZpbHRlcigKICAgICAgICAgICAgICAgICAgICAgKGlmX2FueShjKGtlZ2dfaGl0OnBmYW1faGl0cyksIH4gZ3JlcGwoImNvYmFsdCIsIC4pKSkgfAogICAgICAgICAgICAgICAgICAgICAoaWZfYW55KGMoa2VnZ19oaXQ6cGZhbV9oaXRzKSwgfiBncmVwbCgiY29iIiwgLikpKSB8CiAgICAgICAgICAgICAgICAgICAgIChpZl9hbnkoYyhrZWdnX2hpdDpwZmFtX2hpdHMpLCB+IGdyZXBsKCJjeWFuaWRlIiwgLikpKXwKICAgICAgICAgICAgICAgICAgICAgKGlmX2FueShjKGtlZ2dfaGl0OnBmYW1faGl0cyksIH4gZ3JlcGwoImhjbiIsIC4pKSl8CiAgICAgICAgICAgICAgICAgICAgIChpZl9hbnkoYyhrZWdnX2hpdDpwZmFtX2hpdHMpLCB+IGdyZXBsKCJjeXRvY2hyb21lIiwgLikpKXwKICAgICAgICAgICAgICAgICAgICAgIyhpZl9hbnkoYyhrZWdnX2hpdDpwZmFtX2hpdHMpLCB+IGdyZXBsKCJoeWRyb2dlbmFzZSIsIC4pKSl8IHRoaXMgaXMgbm9uLXNwZWNpZmljIGFuZCBwaWNrcyB1cCBhbnl0aGluZyB3aXRoIGRlaHlkcm9nZW5hc2UsIGNvbW1lbnQgb3V0CiAgICAgICAgICAgICAgICAgICAgIChpZl9hbnkoYyhrZWdnX2hpdDpwZmFtX2hpdHMpLCB+IGdyZXBsKCJzaWRlcm9waG9yZSIsIC4pKSkpICU+JQogICAgICAgICAgICAgICAgICAgIGRwbHlyOjpzZWxlY3Qoc2NhZmZvbGQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVfcG9zaXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0X3Bvc2l0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRfcG9zaXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGtvX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBrZWdnX2hpdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pcmVmX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICB1bmlyZWZfaGl0KQoKI1dyaXRlIHRoZSB0YWJsZSB0byBzYXZlIHRoZSBzb3VyY2UgZGF0YQp3cml0ZS50YWJsZShjb3Jyb3Npb25fcGF0aHdheXMsIGZpbGUgPSAiU3VwcERhdGFfUHNldWRvbW9uYXNfY2hsb3JvcmFwaGlzX2F1cmVvZmFjaWVuc19wdXRhdGl2ZV9jb3Jyb3Npb25fcGF0aHdheXMudHN2Iiwgc2VwID0gIlx0Iiwgcm93Lm5hbWVzID0gRkFMU0UpCmBgYAoKIyMgU3VtbWFyeSBvZiBrZXkgYW50aVNNQVNIIGJpb3N5bnRoZXRpYyBnZW5lIGNsdXN0ZXIgcmVnaW9ucwoKKmtleSBiaW9zeW50aGV0aWMgZ2VuZXMqIGFyZSBkZW5vdGVkIGJ5IGFzdGVyaXNrcyBpbiBtYXJrZG93biBmb3JtYXQuCgojIyMgUmVnaW9uIDIgKGh5ZHJvZ2VuIGN5YW5pZGUgY2x1c3Rlcik6IDI5NTE0ODMgdG8gMjk2NDQ1NQpgYGB7cn0KUmVnaW9uMiA8LSBQc2V1ZG9tb25hc19jaGxvcm9yYXBoaXNfYXVyZW9mYWNpZW5zX2Fubm90YXRpb25zICU+JSBmaWx0ZXIoc3RhcnRfcG9zaXRpb24gPj0gMjk1MTQ4MyAmIGVuZF9wb3NpdGlvbiA8PTI5NjQ0NTUpCmBgYAoKR2VuZXMgaW4gaHlkcm9nZW4gY3lhbmlkZS1jbHVzdGVyOgotICpjdGcxXzI1OTEqOiAyOTU2NDgzIC0gMjk1NjgwMCAtLT4gaHlkcm9nZW4gY3lhbmlkZSBzeW50aGFzZSBIY25BIFtFQzoxLjQuOTkuNV0gKEMgZ3JhZGUsIEtFR0cgSUQgPSBLMTA4MTQpCi0gKmN0ZzFfMjU5Mio6IDI5NTY3OTcgLSAyOTU4MjA2IC0tPiBoeWRyb2dlbiBjeWFuaWRlIHN5bnRoYXNlIEhjbkIgW0VDOjEuNC45OS41XSAoQiBncmFkZSwgS0VHRyBJRCA9IEsxMDgxNSkKLSAqY3RnMV8yNTkzKjogMjk1ODE5OSAtIDI5NTk0NTUgLS0+IGh5ZHJvZ2VuIGN5YW5pZGUgc3ludGhhc2UgSGNuQyBbRUM6MS40Ljk5LjVdIChCIGdyYWRlLCBLRUdHIElEID0gSzEwODE2KQotIGN0ZzFfMjU5NDogMjk1OTYxOCAtIDI5NjAyMjMgLS0+IGdsdXRhdGhpb25lIFMtdHJhbnNmZXJhc2UgW0VDOjIuNS4xLjE4XSAoQiBncmFkZSwgS0VHRyBJRCA9IEswMDc5OSkKCiMjIyBSZWdpb24gNiAoTkktc2lkZXJvcGhvcmUpOiAzODMyODM3IHRvIDM4Njk4MjEKYGBge3J9ClJlZ2lvbjYgPC0gUHNldWRvbW9uYXNfY2hsb3JvcmFwaGlzX2F1cmVvZmFjaWVuc19hbm5vdGF0aW9ucyAlPiUgZmlsdGVyKHN0YXJ0X3Bvc2l0aW9uID49IDM4MzI4MzcgJiBlbmRfcG9zaXRpb24gPD0zODY5ODIxKQpgYGAKCkdlbmVzIGluIE5JLXNpZGVyb3Bob3JlIGNsdXN0ZXI6CgotICpjdGcxXzMzNzIqOiAzODQ2ODM3IC0gMzg0ODczNSAtLT4gKnN0YXBoeWxvZmVycmluKiBCIHN5bnRoYXNlIFtFQzo2LjMuMi41Nl0gKEIgZ3JhZGUgS0VHRyBJRCA9IEsyMzM3NSkKLSBjdGcxXzMzNzM6IDM4NDg3NDAgLSAzODQ5NTEzIC0tPiAqc3RhcGh5bG9mZXJyaW4qIEIgYmlvc3ludGhlc2lzIGNpdHJhdGUgc3ludGhhc2UgKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMjMzNzYpCi0gKmN0ZzFfMzM3NCo6IDM4NDk1MDcgLSAzODUxMzY5IC0tPiAyLVsoTC1hbGFuaW4tMy15bGNhcmJhbW95bCltZXRoeWxdLTMtKDItYW1pbm9ldGh5bGNhcmJhbW95bCktMi1oeWRyb3h5cHJvcGFub2F0ZSBzeW50aGFzZSBbRUM6Ni4zLjIuNTVdIChCIGdyYWRlLCBLRUdHIElEID0gSzIzMzc0KQotIGN0ZzFfMzM3NTogMzg1MTM5NCAtIDM4NTI4MTIgLS0+IFVuaVJlZjkwX0EwQTU1NFA3WTUgREhBMiBmYW1pbHkgZWZmbHV4IE1GUyB0cmFuc3BvcnRlciBwZXJtZWFzZSBzdWJ1bml0IG49MzAgVGF4PVBzZXVkb21vbmFkYWNlYWUgVGF4SUQ9MTM1NjIxIFJlcElEPUEwQTU1NFA3WTVfOVBTRUQgKEIgZ3JhZGUsIG5vIGhpdCBpbiBLRUdHKQotIGN0ZzFfMzM3NjogMzg1MjgwOSAtIDM4NTQwMjkgLS0+IGRpYW1pbm9waW1lbGF0ZSBkZWNhcmJveHlsYXNlIFtFQzo0LjEuMS4yMF0gKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMDE1ODYpCi0gKmN0ZzFfMzM3Nyo6IDM4NTQwMjIgLSAzODU1ODIxIC0tPiBVbmlSZWY5MF9BMEEwQzVFTDY5IEFjc0QgcHJvdGVpbiBuPTcwIFRheD1Qc2V1ZG9tb25hZGFjZWFlIFRheElEPTEzNTYyMSBSZXBJRD1BMEEwQzVFTDY5XzlQU0VEIChCIGdyYWRlLCBubyBoaXQgaW4gS0VHRykKCiMjIyBSZWdpb24gNyAoaHlkcm9nZW4gY3lhbmlkZSBjbHVzdGVyKTogMzg4ODg1NCB0byAzOTAxNzAxCmBgYHtyfQpSZWdpb243IDwtIFBzZXVkb21vbmFzX2NobG9yb3JhcGhpc19hdXJlb2ZhY2llbnNfYW5ub3RhdGlvbnMgJT4lIGZpbHRlcihzdGFydF9wb3NpdGlvbiA+PSAzODg4ODU0ICYgZW5kX3Bvc2l0aW9uIDw9MzkwMTcwMSkKYGBgCgotIGN0ZzFfMzQwNTogMzg5MDk4NCAtIDM4OTI0NDEgLS0+IHN1Y2NpbmF0ZS1zZW1pYWxkZWh5ZGUgZGVoeWRyb2dlbmFzZSAvIGdsdXRhcmF0ZS1zZW1pYWxkZWh5ZGUgZGVoeWRyb2dlbmFzZSBbRUM6MS4yLjEuMTYgMS4yLjEuNzkgMS4yLjEuMjBdIChCIGdyYWRlLCBLRUdHIElEID0gSzAwMTM1KQotIGN0ZzFfMzQwNjogMzg5MjcwMCAtIDM4OTM4NTcgLS0+IGFjZXR5bG9ybml0aGluZSBkZWFjZXR5bGFzZSBbRUM6My41LjEuMTZdIChCIGdyYWRlLCBLRUdHIElEID0gSzAxNDM4KQotICpjdGcxXzM0MDcqOiAzODkzODU0IC0gMzg5NTAwOCAtLT4gVW5pUmVmOTBfQTBBQTQ1WElOMCBTYXJjb3NpbmUgb3hpZGFzZSBzdWJ1bml0IGJldGEgbj01IFRheD1Qc2V1ZG9tb25hcyBUYXhJRD0yODYgUmVwSUQ9QTBBQTQ1WElOMF85UFNFRCAobm8gS0VHRyBoaXQsIEIgZ3JhZGUsIFVuaVJlZiBJRCA9IEEwQUE0NVhJTjBfOVBTRUQpCiAgLSBDYXRhbHl6ZXMgb3hpZGF0aXZlIGRlbWV0aHlsYXRpb24gb2Ygc2FyY29zaW5lIChOLW1ldGh5bGdseWNpbmUpIHRvIHlpZWxkIGdseWNpbmUKLSAqY3RnMV8zNDA4KjogMzg5NTAwNSAtIDM4OTY0MTEgLS0+IFVuaVJlZjkwX0EwQTNHN0swRTIgT3BpbmUgb3hpZGFzZSBzdWJ1bml0IEEgbj0zOSBUYXg9UHNldWRvbW9uYXMgVGF4SUQ9Mjg2IFJlcElEPUEwQTNHN0swRTJfOVBTRUQsIChubyBLRUdHIGhpdCwgQiBncmFkZSwgVW5pcmVmIElEID0gQTBBM0c3SzBFMl85UFNFRCkKICAtIENsZWF2ZXMgb3BpbmVzIGludG8gYW1pbm8gYWNpZHMgYW5kIHB5cnV2YXRlCi0gKmN0ZzFfMzQwOSo6IDM4OTYzOTMgLSAzODk2NzAxIC0tPiBVbmlSZWY5MF9BMEE1TTdDVEQxICgyRmUtMlMpLWJpbmRpbmcgcHJvdGVpbiBuPTE0IFRheD1Qc2V1ZG9tb25hZGFjZWFlIFRheElEPTEzNTYyMSBSZXBJRD1BMEE1TTdDVEQxXzlQU0VEIChDIGdyYWRlLCBubyBLRUdHIGhpdCwgVW5pUmVmIElEID0gQTBBNU03Q1REMV85UFNFRCkKLSBjdGcxXzM0MTA6IDM4OTY2OTggLSAzODk4NTM5IC0tPiBwZXB0aWRlL25pY2tlbCB0cmFuc3BvcnQgc3lzdGVtIEFUUC1iaW5kaW5nIHByb3RlaW4gKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMDIwMzEpCi0gY3RnMV8zNDExOiAzODk4NTQxIC0gMzg5OTQxNiAtLT4gVW5pUmVmOTBfQTBBMEMxWlNVNiBETkEtZGlyZWN0ZWQgUk5BIHBvbHltZXJhc2Ugc3VidW5pdCBhbHBoYSBuPTMwIFRheD1Qc2V1ZG9tb25hZGFjZWFlIFRheElEPTEzNTYyMSBSZXBJRD1BMEEwQzFaU1U2X1BTRUZMIChubyBLRUdHIGhpdCwgQiBncmFkZSwgVW5pcmVmIElEID0gQTBBMEMxWlNVNl9QU0VGTCkKLSBjdGcxXzM0MTI6IDM4OTk0MTMgLSAzOTAwMzY5IC0tPiBwZXB0aWRlL25pY2tlbCB0cmFuc3BvcnQgc3lzdGVtIHBlcm1lYXNlIHByb3RlaW4gKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMDIwMzMpCgojIyMgUmVnaW9uIDEwIChOUlAtbWV0YWxsb3Bob3JlKTogNTA1NjQzNCB0byA1MTU1NDA3CmBgYHtyfQpSZWdpb24xMCA8LSBQc2V1ZG9tb25hc19jaGxvcm9yYXBoaXNfYXVyZW9mYWNpZW5zX2Fubm90YXRpb25zICU+JSBmaWx0ZXIoc3RhcnRfcG9zaXRpb24gPj0gNTA1NjQzNCAmIGVuZF9wb3NpdGlvbiA8PTUxNTU0MDcpCmBgYAoKLSAqY3RnMV80NDc0KjogNSwwNzYsNDM0IC0gNSwwNzcsNzY4IC0tPiBMLW9ybml0aGluZSBONS1tb25vb3h5Z2VuYXNlIFtFQzoxLjE0LjEzLjE5NSAxLjE0LjEzLjE5Nl0gKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMTA1MzEpCi0gY3RnMV80NDc1OiA1LDA3Nyw5MDAgLSA1LDA3OCw0OTYgLS0+IFVuaVJlZjkwX0EwQTE2NVlHWDQgUk5BIHBvbHltZXJhc2Ugc3VidW5pdCBzaWdtYSBuPTQgVGF4PVBzZXVkb21vbmFzIFRheElEPTI4NiBSZXBJRD1BMEExNjVZR1g0X1BTRUZMIChDIGdyYWRlLCBubyBLRUdHIElEKQotIGN0ZzFfNDQ3NjogNSwwNzgsNzE2IC0gNSwwNzksODg4IC0tPiBtZW1icmFuZSBmdXNpb24gcHJvdGVpbiwgbWFjcm9saWRlLXNwZWNpZmljIGVmZmx1eCBzeXN0ZW0gKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMTM4ODgpCi0gY3RnMV80NDc3OiA1LDA3OSw4ODkgLSA1LDA4MSw4NjIgLS0+IG1hY3JvbGlkZSB0cmFuc3BvcnQgc3lzdGVtIEFUUC1iaW5kaW5nL3Blcm1lYXNlIHByb3RlaW4gW0VDOjcuNi4yLi1dIChCIGdyYWRlLCBLRUdHIElEID0gSzA1Njg1KQotIGN0ZzFfNDQ3ODogNSwwODEsODcwIC0gNSwwODMsMjc5IC0tPiBvdXRlciBtZW1icmFuZSBwcm90ZWluLCBtdWx0aWRydWcgZWZmbHV4IHN5c3RlbSAoQiBncmFkZSwgS0VHRyBJRCA9IEsxODEzOSkKLSAqY3RnMV80NDc5KjogNSwwODMsMzU1IC0gNSwwODQsOTc3IC0tPiBVbmlSZWY5MF9BMEE1NTRQQUMwIFR3aW4tYXJnaW5pbmUgdHJhbnNsb2NhdGlvbiBzaWduYWwgZG9tYWluLWNvbnRhaW5pbmcgcHJvdGVpbiBuPTE5IFRheD1Qc2V1ZG9tb25hZGFjZWFlIFRheElEPTEzNTYyMSBSZXBJRD1BMEE1NTRQQUMwXzlQU0VEIChCIGdyYWRlLCBubyBLRUdHIGhpdCkKLSBjdGcxXzQ0ODA6IDUsMDg1LDE4NiAtIDUsMDg2LDU5NSAtLT4gbWVtYnJhbmUgZGlwZXB0aWRhc2UgW0VDOjMuNC4xMy4xOV0gKEIgZ3JhZGUsIEtFR0cgSUQgPSBLMDEyNzMpCi0gY3RnMV80NDgxOiA1LDA4Niw2MTcgLSA1LDA4Nyw5MTUgLS0+IFVuaVJlZjkwX0EwQTJDOUVRTjEgSXNvcGVuaWNpbGxpbiBOIGVwaW1lcmFzZSBDZWZEIG49NTYgVGF4PVBzZXVkb21vbmFkYWNlYWUgVGF4SUQ9MTM1NjIxIFJlcElEPUEwQTJDOUVRTjFfUFNFUEggKEIgZ3JhZGUsIG5vIEtFR0cgaGl0KQotICpjdGcxXzQ0ODIqOiA1LDA4Nyw5NTkgLSA1LDA4OCw4NTUgLS0+IFVuaVJlZjkwX1E0Szk5NyBDaHJvbW9waG9yZSBtYXR1cmF0aW9uIHByb3RlaW4gKlB2ZE8qIG49NTUgVGF4PVBzZXVkb21vbmFkYWNlYWUgVGF4SUQ9MTM1NjIxIFJlcElEPVE0Szk5N19QU0VGNSAoQiBncmFkZSwgbm8gS0VHRyBoaXQpCi0gY3RnMV80NDgzOiA1LDA4OCw5MTAgLSA1LDA4OSw3NzMgLS0+IFVuaVJlZjkwX1E0Szk5NiBwaG9zcGhvcmlib3N5bGdseWNpbmFtaWRlIGZvcm15bHRyYW5zZmVyYXNlIDEgbj00OSBUYXg9UHNldWRvbW9uYWRhY2VhZSBUYXhJRD0xMzU2MjEgUmVwSUQ9UTRLOTk2X1BTRUY1IChCIGdyYWRlLCBubyBLRUdHIGhpdCkKLSBjdGcxXzQ0ODQ6IDUsMDg5LDk2MSAtIDUsMDkxLDYxMyAtLT4gcHV0YXRpdmUgcHlvdmVyZGluIHRyYW5zcG9ydCBzeXN0ZW0gQVRQLWJpbmRpbmcvcGVybWVhc2UgcHJvdGVpbiAoQiBncmFkZSwgS0VHRyBJRCA9IEswNjE2MCkKLSBjdGcxXzQ0ODU6IDUsMDkxLDcxNCAtIDUsMDk0LDE4MiAtLT4gb3V0ZXItbWVtYnJhbmUgcmVjZXB0b3IgZm9yIGZlcnJpYyBjb3Byb2dlbiBhbmQgZmVycmljLXJob2RvdG9ydWxpYyBhY2lkIChCIGdyYWRlLCBLRUdHIElEID0gSzE2MDg4KQotICpjdGcxXzQ0ODYqOiA1LDA5NCw1NzAgLSA1LDEwNyw4MDUgLS0+IFVuaVJlZjkwX0EwQTU1NFBBQjYgQW1pbm8gYWNpZCBhZGVueWxhdGlvbiBkb21haW4tY29udGFpbmluZyBwcm90ZWluIG49MjIgVGF4PVBzZXVkb21vbmFzIFRheElEPTI4NiBSZXBJRD1BMEE1NTRQQUI2XzlQU0VEIChCIGdyYWRlLCBubyBLRUdHIGhpdCkKLSAqY3RnMV80NDg3KjogNSwxMDcsODE4IC0gNSwxMTQsNDE0IC0tPiBVbmlSZWY5MF9BMEE1NTRQQUMyIE5vbi1yaWJvc29tYWwgcGVwdGlkZSBzeW50aGV0YXNlIG49MjYgVGF4PVBzZXVkb21vbmFzIFRheElEPTI4NiBSZXBJRD1BMEE1NTRQQUMyXzlQU0VEIChCIGdyYWRlLCBubyBLRUdHIGhpdCkKLSAqY3RnMV80NDg4KjogNSwxMTQsNDE0IC0gNSwxMjUsNTc2IC0tPiBVbmlSZWY5MF9VUEkwMDI0MDdDOUREIGFtaW5vIGFjaWQgYWRlbnlsYXRpb24gZG9tYWluLWNvbnRhaW5pbmcgcHJvdGVpbiBuPTQgVGF4PVBzZXVkb21vbmFzIGNobG9yb3JhcGhpcyBUYXhJRD01ODc3NTMgUmVwSUQ9VVBJMDAyNDA3QzlERCAoQiBncmFkZSwgbm8gS0VHRyBoaXQpCgojIyMgUmVnaW9uIDExIChOUlBTKTogNTE4OTQ1NiB0byA1MjQyNDcyCmBgYHtyfQpSZWdpb24xMSA8LSBQc2V1ZG9tb25hc19jaGxvcm9yYXBoaXNfYXVyZW9mYWNpZW5zX2Fubm90YXRpb25zICU+JSBmaWx0ZXIoc3RhcnRfcG9zaXRpb24gPj0gNTE4OTQ1NiAmIGVuZF9wb3NpdGlvbiA8PTUyNDI0NzIpCmBgYAoKTlJQUyByZWdpb24gaGVyZSBpcyByZWFsbHkgb25seSBvbmUgZ2VuZToKLSAqY3RnMV80NTYzKjogNTIwOTQ1NiAtIDUyMjI0NzIgLS0+IFVuaVJlZjkwX0EwQTU1NFBFTDcgTm9uLXJpYm9zb21hbCBwZXB0aWRlIHN5bnRoZXRhc2Ugbj0yOSBUYXg9UHNldWRvbW9uYWRhY2VhZSBUYXhJRD0xMzU2MjEgUmVwSUQ9QTBBNTU0UEVMN185UFNFRCAoQiBncmFkZSwgbm8gS0VHRyBoaXQpCgo=